简体   繁体   English

避免Iterator ConcurrentModificationException的方法

[英]Ways to avoid Iterator ConcurrentModificationException

As far as I know there are two ways to avoid ConcurrentModificationException while one threading iterates the collection and another thread modifies the collection. 据我所知,有两种方法可以避免ConcurrentModificationException,一个线程迭代该集合,另一个线程修改该集合。

  1. client-locking, basically lock the collection during the iteration. 客户端锁定,基本上是在迭代过程中锁定集合。 Other threads that need to access the collection will block until the iteration is complete. 其他需要访问集合的线程将阻塞,直到迭代完成。
  2. "thread-confined" that clones the collection and iterate the copy. “线程限制”克隆集合并迭代副本。

I am wondering are there any other alternatives ? 我想知道还有其他选择吗? because the first way obvious is undesirable and poor performance-wise, if the collection is large that other threads could wait for a long time. 因为第一种显而易见的方式是不受欢迎的,而且性能很差,如果集合很大,其他线程可能会等待很长时间。 second way I am not sure that since we clone the collection, and iterate the copy, so if other threads come in and modify the original one, then the copied one becomes stale right ? 第二种方式我不确定,因为我们克隆了集合并迭代了副本,所以如果其他线程进入并修改了原始线程,那么复制的线程就会过时了吧? does that mean we need to restart over by cloning and iterate it again once it's modified ? 这是否意味着我们需要通过克隆重新开始并在修改后再次迭代它?

I am wondering are there any other alternatives ? 我想知道还有其他选择吗?

Use one of the concurrent collections which doesn't throw this exception. 使用其中一个不会抛出此异常的并发集合。 Instead they provide weak consistency. 相反,它们提供了较弱的一致性。 ie an added or delete element may or may not appear while iterating. 也就是说,添加或删除元素在迭代过程中可能会出现,也可能不会出现。

http://docs.oracle.com/javase/tutorial/essential/concurrency/collections.html http://docs.oracle.com/javase/tutorial/essential/concurrency/collections.html

The java.util.concurrent package includes a number of additions to the Java Collections Framework. java.util.concurrent包中包含许多Java Collections Framework的附加内容。 These are most easily categorized by the collection interfaces provided: 这些最容易通过提供的集合接口进行分类:

  • BlockingQueue defines a first-in-first-out data structure that blocks or times out when you attempt to add to a full queue, or retrieve from an empty queue. BlockingQueue定义了先进先出数据结构,当您尝试添加到完整队列或从空队列中检索时,该数据结构会阻塞或超时。
  • ConcurrentMap is a subinterface of java.util.Map that defines useful atomic operations. ConcurrentMap是java.util.Map的子接口,它定义了有用的原子操作。 These operations remove or replace a key-value pair only if the key is present, or add a key-value pair only if the key is absent. 仅当密钥存在时,这些操作才会删除或替换键值对,或仅在密钥不存在时才添加键值对。 Making these operations atomic helps avoid synchronization. 使这些操作原子化有助于避免同步。 The standard general-purpose implementation of ConcurrentMap is ConcurrentHashMap, which is a concurrent analog of HashMap. ConcurrentMap的标准通用实现是ConcurrentHashMap,它是HashMap的并发模拟。
  • ConcurrentNavigableMap is a subinterface of ConcurrentMap that supports approximate matches. ConcurrentNavigableMap是ConcurrentMap的子接口,支持近似匹配。 The standard general-purpose implementation of ConcurrentNavigableMap is ConcurrentSkipListMap, which is a concurrent analog of TreeMap. ConcurrentNavigableMap的标准通用实现是ConcurrentSkipListMap,它是TreeMap的并发模拟。

你可以使用java.util.Concurrent中的 Class,比如CopyOnWriteArrayList

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM