2014-10-04 13 views
2

我有以下情况:的Java:ConcurrentModificationException的,3线,不同的清单,相同的对象

在主函数,如果一些控制器I类检索我的DB 10个的产品对象。这些都保存在一个ArrayList对象中。

之后,我创建了三个扩展Runnable的类,并将每个类的product-ArrayList赋予构造函数。

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

this.products = new ArrayList(); 
products.addAll(productListParam); 

后来我开始每三个线程,它们遍历其本地产品,列表和也修改它。

我得到一个ConcurrentModificationException的同时遍历本地产品的ArrayList ..

这究竟是为什么?我假设如果我在每个线程中创建一个完整的新列表,我可以根据需要在本地修改此列表,而不必关心其他线程 - 我是对的吗?或者,从本地列表中删除某个对象是否会以某种方式影响对象,以便其他线程抛出并发修改异常?

其实堆栈跟踪的样子:

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) 

和Classname.java在326的样子:

325:List<Product> productsToDelete = new ArrayList(); 
326:for(Product p: products){ 
     ... 
     if(xy){ 
       productsToDelete.add(p); 
     } 
    } 
    products.removeAll(productsToRemove); 

也许有人对我暗示什么,我做错了什么?

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

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

+0

试试这个https://stackoverflow.com/a/46844254/5309409 – 2017-10-20 07:28:42

回答

3

您不能在迭代其元素的增强for循环中修改Collection。即使你只有一个线程也没有。

您不包括内部增强的for循环的代码,但如果你需要做的里面是删除列表中的元素,你可以使用一个明确的迭代器。

Iterator<Product> iter = products.iterator(); 
While (iter.hasNext() { 
    Product p = iter.next(); 
    .... 
    if (some condition) 
     iter.remove(); 
    .... 
} 
+0

对不起,我没有包含for循环的代码,但根本没有修改。迭代产品对象仅用于读取模式以获取一些信息。 从列表中没有任何东西或添加。产品对象内部也没有任何变化。 此外stacktrace指向我从未见过的for(Product p:products)语句。 – 2014-10-04 14:57:34

+0

@dacrow你的问题意味着你正在修改这些列表 - “或者从本地列表中删除某个对象会影响这个列表。 ..'。你在哪里修改它们? – Eran 2014-10-04 14:58:59

+0

对不起伊兰为我的非凡描述,我编辑了我的问题。 – 2014-10-04 15:05:40

0

对不起,大家打扰你,我做了一个不好的初学者的错!

我设置的提到产品 -ArrayList手动后来从一些其他的代码基础,没有覆盖新的ArrayList ..所以所有的线程再次使用只有一个ArrayList和该ConcurrentModificationException的发生。

正如你这个例子中看到的,总是仔细检查你的代码:)

对不起,打扰你..

相关问题