【问题标题】:Adding elements to a HashSet while Iterating [duplicate]迭代时将元素添加到 HashSet [重复]
【发布时间】:2020-04-22 02:31:18
【问题描述】:

所以我的程序是paint的一个版本。

它创建了一个画布,并允许我通过使用HashSetIterator 从鼠标获取Point 来用鼠标在画布上绘画。

它还通过DatagramSocket 连接到另一个相同的程序,并将它生成的Point 发送到另一个在其画布上显示它的程序。

为此,我使用Runnable 线程侦听传入的Point 并将它们添加到HashSet

我的问题是我得到java.util.ConcurrentModificationException,因为我在绘画时通过线程从连接的程序将Point 添加到HashSet

我不知道如何解决此异常,因为我希望画布能够实时更新。


使用CopyOnWriteArraySet 解决了这个问题,我可以简单地替换我的HashSet :) 感谢您的支持!

【问题讨论】:

  • 在循环中创建一个新集,然后将所有集添加到原始集。在添加过程中仍然会出现并发问题,因此您也必须注意这一点。

标签: java multithreading iterator hashset


【解决方案1】:

使用ConcurrentSkipListSet 代替HashSet。此 Set 实现是有序线程安全

作为MikeFHay mentions,您还可以使用另一个线程安全 Set 实现 - ConcurrentHashMap.KeySetView。它可以通过使用ConcurrentHashMap.newKeySet() 方法来实例化。此 Set 更快然后 ConcurrentSkipListSet 并且是无序

【讨论】:

  • 或者ConcurrentHashMap.newKeySet(),同样支持并发修改,一般比ConcurrentSkipListSet快。
【解决方案2】:

您可以通过锁定集合来避免这种情况。在两个线程中使用“同步”块并在访问它们之前锁定集合,这样没有两个线程同时修改集合。

This might help

【讨论】:

  • Dope,但这不会导致每个程序等待使用连接程序中的点更新画布,直到它完成读取用户输入?
  • 链接中也提到了这个缺点。锁定对象将同时停止更新和检索。但是,如果线程有一段时间没有锁定对象,则可以使用此方法来避免 ConcurrentModificationException。如果对象未被修改,请确保释放锁定。避免锁定对象一段时间。
猜你喜欢
  • 2010-11-09
  • 2021-12-02
  • 2015-08-16
  • 1970-01-01
  • 2011-11-16
  • 2015-06-30
  • 2014-05-01
  • 1970-01-01
  • 2023-04-02
相关资源
最近更新 更多