【问题标题】:Java: ConcurrentModificationException, 3 threads, different lists, same objectsJava:ConcurrentModificationException,3 个线程,不同的列表,相同的对象
【发布时间】:2014-11-29 09:22:16
【问题描述】:

我有以下情况:

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

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

在每个构造函数中都创建了一个新的本地 ArrayList,并添加了 product-ArrayList 中的对象:

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

之后,我启动三个线程中的每一个,它们遍历本地产品列表并对其进行修改。

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

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

实际上堆栈跟踪看起来像:

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 进行任何修改。它们只被添加到第二个“toBeRemoved”列表中,以便在 for 循环完成后删除它们。我编辑了上面的代码。

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

【问题讨论】:

标签: java multithreading arraylist concurrentmodification


【解决方案1】:

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

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

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

【讨论】:

  • 对不起,我没有包含来自 for 循环的代码,但根本没有做任何修改。迭代的产品对象只是在读取模式下用于获取一些信息。列表中没有任何内容或添加内容。产品对象内部也没有任何变化。此外,堆栈跟踪指向我以前从未见过的 for(Product p: products) 语句..
  • @dacrow 您的问题暗示您正在修改列表 - Or does the removal of some object from a local list affect the...。你在哪里修改它们?
  • 抱歉 Eran 的描述不准确,我已经编辑了我的问题。
【解决方案2】:

对不起,打扰你了,我犯了一个糟糕的初学者错误!

我稍后从其他代码基础手动设置了提到的 product-ArrayList 并确实覆盖了新的 ArrayList.. 所以所有线程再次只使用一个 ArrayList 并且发生了 ConcurrentModificationException。

正如您在此示例中看到的,请务必仔细检查您的代码 :)

很抱歉打扰你..

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-27
    • 1970-01-01
    • 2017-12-16
    • 2013-05-26
    • 2016-04-18
    • 2023-04-07
    • 1970-01-01
    相关资源
    最近更新 更多