Java 循环遍历列表时的ConcurrentModificationException

Java 循环遍历列表时的ConcurrentModificationException,java,multithreading,concurrency,Java,Multithreading,Concurrency,我有一个私有类变量,它被声明为 private List<String> list= new ArrayList<String>(); 我正在寻找建议,以避免这个问题与最小的变化。该类变量由该类中的多个方法共享和使用。既然您已经知道列表将由多个线程访问,请声明一个线程安全的列表 List<String> list= Collections.synchronizedList(new ArrayList<String>()); List List=

我有一个私有类变量,它被声明为

private List<String> list= new ArrayList<String>();

我正在寻找建议,以避免这个问题与最小的变化。该类变量由该类中的多个方法共享和使用。

既然您已经知道列表将由多个线程访问,请声明一个线程安全的
列表

List<String> list= Collections.synchronizedList(new ArrayList<String>());
List List=Collections.synchronizedList(新的ArrayList());

集合上使用
迭代器时,必须使用
迭代器。remove()
而不是
集合。remove()
以防止出现
ConcurrentModificationException
。但是,如果有多个线程,则可能还需要使用
Collections.syncrhonizedList()

从Oracle Java文档:

List list = Collections.synchronizedList(new ArrayList());
  ...
synchronized (list) {
    Iterator i = list.iterator(); // Must be in synchronized block
    while (i.hasNext())
        foo(i.next());
}

您可以尝试CopyOnWriteList,JavaDocs说:

该数组在迭代器的生命周期内不会更改,因此不可能发生干扰,并且迭代器保证不会抛出ConcurrentModificationException

List List=new CopyOnWriteArrayList();

鉴于javadocs听起来像是OP也需要使用synchronized关键字显式同步。因此,仅仅更改变量以利用Collections.synchronizedList可能还不够。感谢您的回答,但我认为我给出了错误的方向。因此,理想的情况是当多个线程访问这个类时,每个线程都使用这个列表来存储和检索自己的计算。当前私有列表=新建ArrayList();将列表放在多线程共享的堆中。我想每个线程都有自己的列表副本。但是我们在当前的实现中得到了ConcurrentModificationException异常。我不太明白你说的每个线程都有自己的列表副本是什么意思。当一个线程存储新的内容时,它是否应该在其他线程中更新?每个线程将在此列表中存储不同的结果(因为每个线程将调用此类中的另一个方法,该方法将再次使用新的ArrrayList初始化列表)我们希望将该类变量设置为每个线程的局部变量,而不是跨多个线程共享。@如果您在遍历列表时仍在修改列表,请查看
ListIterator
。不能调用
list.add()
list.remove()
或任何将直接更改列表中元素数量的操作。您必须使用
ListIterator
添加/删除元素。我现在的问题实际上是如何将此变量(列表)设置为每个线程的本地变量?把它从一堆移到另一堆?如果大多数活动都是写的,我们是否有其他的结构来确保线程安全并避免concurrentmodification异常?
List list = Collections.synchronizedList(new ArrayList());
  ...
synchronized (list) {
    Iterator i = list.iterator(); // Must be in synchronized block
    while (i.hasNext())
        foo(i.next());
}
 List<String> list = new CopyOnWriteArrayList<>();