Java:ConcurrentModificationException,3个线程,不同的列表,相同的对象

Java:ConcurrentModificationException,3个线程,不同的列表,相同的对象,java,multithreading,arraylist,concurrentmodification,Java,Multithreading,Arraylist,Concurrentmodification,我有以下情况: 在主函数中,如果某个控制器类从数据库中检索到10个产品对象。它们保存在ArrayList对象中 之后,我创建了三个扩展Runnable的类,并将ProductArrayList提供给每个类到构造函数中 在每个构造函数中创建一个新的本地ArrayList,并添加产品ArrayList中的对象: this.products = new ArrayList(); products.addAll(productListParam); 之后,我启动三个线程中的每一个,它们迭代本地产品列表

我有以下情况:

在主函数中,如果某个控制器类从数据库中检索到10个产品对象。它们保存在ArrayList对象中

之后,我创建了三个扩展Runnable的类,并将ProductArrayList提供给每个类到构造函数中

在每个构造函数中创建一个新的本地ArrayList,并添加产品ArrayList中的对象:

this.products = new ArrayList();
products.addAll(productListParam);
之后,我启动三个线程中的每一个,它们迭代本地产品列表并对其进行修改

我在迭代本地产品ArrayList时遇到ConcurrentModificationException

为什么会这样?我假设,如果我在每个线程中创建一个完整的新列表,我可以在本地任意修改它,而不必关心其他线程,对吗?或者从本地列表中删除某个对象是否会以某种方式影响pbjects,从而导致其他线程抛出并发修改异常

实际上,stacktrace看起来像:

java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:819)
at java.util.ArrayList$Itr.next(ArrayList.java:791)
at com.x.y.class.method(Classname.java:326)
325:List<Product> productsToDelete = new ArrayList();
326:for(Product p: products){
        ...
        if(xy){
              productsToDelete.add(p);
        }
    }
    products.removeAll(productsToRemove);
326处的Classname.java如下所示:

java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:819)
at java.util.ArrayList$Itr.next(ArrayList.java:791)
at com.x.y.class.method(Classname.java:326)
325:List<Product> productsToDelete = new ArrayList();
326:for(Product p: products){
        ...
        if(xy){
              productsToDelete.add(p);
        }
    }
    products.removeAll(productsToRemove);
325:List productsToDelete=new ArrayList();
326:for(产品p:products){
...
if(xy){
productsToDelete.add(p);
}
}
products.removeAll(productsToRemove);
也许有人能告诉我我做错了什么

编辑:在循环内部,产品对象p仅用于读取。此外,没有对products ArrayList进行任何修改。它们仅添加到第二个“toBeRemoved”列表中,以便在for循环完成后删除它们。。我编辑了上面的代码


我想我最感兴趣的问题是,我是否可以创建几个列表对象,通过addAll()方法将相同的产品对象添加到每个列表对象中,然后在每个线程中使用它添加到任何内容,而不必关心其他线程

不能在迭代元素的增强for循环中修改集合。即使你只有一条线也不行

您没有将代码包含在增强的for循环中,但是如果您需要在其中执行的是从列表中删除元素,那么可以使用显式迭代器

Iterator<Product> iter = products.iterator();
While (iter.hasNext() {
    Product p = iter.next();
    ....
    if (some condition)
        iter.remove();
    ....
}
Iterator iter=products.Iterator();
While(iter.hasNext(){
产品p=iter.next();
....
如果(某些条件)
iter.remove();
....
}

很抱歉打扰你们,我犯了一个糟糕的初学者错误

后来,我从其他代码基础上手动设置了提到的产品ArrayList,并覆盖了新的ArrayList。因此,所有线程再次仅使用一个ArrayList,并发生ConcurrentModificationException

正如您在本示例中看到的,请始终仔细检查您的代码:)


很抱歉打扰您。

很抱歉,我没有包含for循环中的代码,但根本没有进行任何修改。迭代的产品对象只是在读取模式下使用,以获取一些信息。没有从列表中提取或添加任何内容。产品对象内部也没有任何变化。此外,stacktrace指向我以前从未见过的for(Product p:products)语句。@dacrow您的问题暗示您正在修改列表-
,或者从本地列表中删除某些对象是否会影响…
。你在哪里修改它们?很抱歉Eran对我的描述不准确,我已经编辑了我的问题。试试这个