简体   繁体   English

Java ConcurrentModificationException:是否可以在迭代时向哈希表添加元素?

[英]Java ConcurrentModificationException: Is it possible to add elements to a hashtable while iterating through it?

I am iterating through a Hashtable and at one point, I add something in to the Hashtable which is clearly giving me a ConcurrentModificationException . 我正在迭代Hashtable并且在某一点上,我在Hashtable添加了一些东西,这显然给了我一个ConcurrentModificationException I understand why I am getting the error, but is there a way around this such that I could still iterate through the Hashtable and add values simultaneously? 我理解为什么我会收到错误,但有没有办法解决这个问题,以至于我仍然可以遍历Hashtable并同时添加值?

From the docs 来自文档

The iterators returned by the iterator method of the collections returned by all of this class's "collection view methods" are fail-fast: if the Hashtable is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove method, the iterator will throw a ConcurrentModificationException. 所有这个类的“集合视图方法”返回的集合的迭代器方法返回的迭代器都是快速失败的:如果在创建迭代器之后的任何时候对Hashtable进行结构修改,除非通过迭代器自己的删除方法,迭代器将抛出ConcurrentModificationException。 Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future. 因此,在并发修改的情况下,迭代器快速而干净地失败,而不是在未来的未确定时间冒着任意的,非确定性行为的风险。 The Enumerations returned by Hashtable's keys and elements methods are not fail-fast. Hashtable的键和元素方法返回的枚举不是快速失败的。

Note that the fail-fast behavior of an iterator cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification. 请注意,迭代器的快速失败行为无法得到保证,因为一般来说,在存在不同步的并发修改时,不可能做出任何硬性保证。 Fail-fast iterators throw ConcurrentModificationException on a best-effort basis. 失败快速迭代器会尽最大努力抛出ConcurrentModificationException。 Therefore, it would be wrong to write a program that depended on this exception for its correctness: the fail-fast behavior of iterators should be used only to detect bugs. 因此,编写依赖于此异常的程序以确保其正确性是错误的:迭代器的快速失败行为应该仅用于检测错误。

If you need this kind of behavior you can safely copy the set of keys and iterate through the copy. 如果您需要这种行为,您可以安全地复制该组密钥并遍历该副本。 Another option if the hashtable is large and copying the keyset is likely to be expensive is to add to a separate collection during the iteration and add the elements of the separate collection post iteration. 如果散列表很大并且复制键集可能很昂贵的另一个选择是在迭代期间添加到单独的集合并添加单独的集合迭代后的元素。

You may also want to know about CopyOnWriteSet, which is specifically designed for safe iteration while set is modified. 您可能还想了解CopyOnWriteSet,它专门为安全迭代而设计,同时修改了set。 Note that iterator sees only the original set. 请注意,迭代器只能看到原始集。 Any additions will not be visible until next iteration. 在下一次迭代之前,任何添加都不可见。

http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/CopyOnWriteArraySet.html http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/CopyOnWriteArraySet.html

This is most useful in many readers / few writers scenario. 这在许多读者/少数作家场景中最有用。 It is unlikely to be the most efficient solution if reading and writing happens in the same code path. 如果在同一代码路径中进行读写,则不太可能是最有效的解决方案。

Make a new Hashtable that you add new entries to; 创建一个新的Hashtable,您可以添加新条目; then when you are done iterating, add in the entries from the first table. 然后当你完成迭代时,添加第一个表中的条目。

Optionally, if you need to, you can skip keys that exist in the original table. (可选)如果需要,可以跳过原始表中存在的键。

Another alternative would be to use a ConcurrentHashMap instead of a HashMap. 另一种方法是使用ConcurrentHashMap而不是HashMap。 However: 然而:

  • The iterators for a ConcurrentHashMap are defined to return objects reflecting a state some time at or after the creation of the iterator. ConcurrentHashMap的迭代器被定义为在创建迭代器时或之后返回反映状态的对象。 A more precise statement of the behaviour is in the javadocs for the relevant methods. 更精确的行为陈述在相关方法的javadoc中。

  • A ConcurrentHashMap is probably slower than a regular HashMap. ConcurrentHashMap可能比常规HashMap慢。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 通过HashMap迭代时出现ConcurrentModificationException - ConcurrentModificationException while iterating through HashMap 如果我们在迭代时最后在ArrayList中添加元素,则抛出ConcurrentModificationException - Throwing ConcurrentModificationException if we add elements in ArrayList at the end while iterating 遍历列表但未修改列表时发生ConcurrentModificationException - ConcurrentModificationException while iterating through a list but not modifying it 迭代Arraylist时的ConcurrentModificationException(不删除) - ConcurrentModificationException while iterating through Arraylist (not removing) 遍历List时发生ConcurrentModificationException,尽管未对其进行任何修改 - ConcurrentModificationException while iterating through List, altough not modifying it 遍历集合以添加项目但抛出 ConcurrentModificationException - Iterating through collections to add items but throwing ConcurrentModificationException 迭代并从 ArrayList 中删除元素时如何避免 java.util.ConcurrentModificationException - How to avoid java.util.ConcurrentModificationException when iterating through and removing elements from an ArrayList 添加 ArrayList 元素时如何避免“ConcurrentModificationException”? - How to avoid "ConcurrentModificationException" while add ArrayList elements? 在遍历元素时删除元素。 removeIf 导致 ConcurrentModificationException - Removing element while iterating through it. removeIf result in ConcurrentModificationException 迭代列表时遇到java.util.ConcurrentModificationException - Running into java.util.ConcurrentModificationException while iterating list
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM