我有以下情况:
在主函数中,如果某个控制器类从我的数据库中检索10个产品对象。它们保存在ArrayList对象中。
之后我创建了三个扩展Runnable的类,并将product-ArrayList赋予每个类到构造函数中。
在每个构造函数中都创建了一个新的本地ArrayList,并添加了product-ArrayList中的对象:
this.products = new ArrayList();
products.addAll(productListParam);
然后我启动三个线程中的每一个,然后迭代它们的本地产品列表并修改它。
我在迭代本地产品ArrayList时遇到ConcurrentModificationException。
为什么会这样?我假设如果我在每个线程中创建一个完整的新列表,我可以在不需要关心其他线程的情况下在本地修改它 - 我是对的吗?或者从本地列表中删除某个对象是否会以某种方式影响pbject,以便其他线程抛出并发修改异常?
实际上堆栈跟踪看起来像:
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)
和326的Classname.java看起来像:
325:List<Product> productsToDelete = new ArrayList();
326:for(Product p: products){
...
if(xy){
productsToDelete.add(p);
}
}
products.removeAll(productsToRemove);
也许有人暗示我做错了什么?
编辑:在循环内部,产品对象p仅用于阅读。此外,没有对products-ArrayList进行任何修改。它们只被添加到第二个“去除”中。列表在for循环结束后删除它们。我编辑了上面的代码。
我认为我对这个问题最感兴趣,如果我可以创建多个列表对象,通过addAll()方法向每个列表对象添加相同的产品对象,然后可以在每个对象中添加任何内容线程没有关心其他线程?!
答案 0 :(得分:3)
您无法在迭代其元素的增强型for循环内修改Collection。即使你只有一个线程也不行。
您没有在增强的for循环中包含代码,但如果您需要在其中执行的操作是从列表中删除元素,则可以使用显式迭代器。
Iterator<Product> iter = products.iterator();
While (iter.hasNext() {
Product p = iter.next();
....
if (some condition)
iter.remove();
....
}
答案 1 :(得分:0)
很抱歉打扰你的人,我初学错误了!
我稍后从其他一些代码基础手动设置了所提到的产品 -ArrayList,并覆盖了新的ArrayList ..所以所有线程只使用了一个ArrayList并发生了ConcurrentModificationException。
正如您在此示例中所看到的,请务必仔细检查您的代码:)
很抱歉打扰你..