1

我的代码导致 java.util.ConcurrentModificationException 错误。这是以下代码。

这是确切的错误:

java.util.ConcurrentModificationException
java.util.ConcurrentModificationException
        at java.util.HashMap$HashIterator.nextEntry(HashMap.java:894)
        at java.util.HashMap$KeyIterator.next(HashMap.java:928)
        at ca.on.oicr.pinery.lims.gsle.GsleClient.getOrders(GsleClient.java:720)

第 720 行是第二个 for 循环

我之前发布了这个问题,并被告知“您在循环中添加订单元素,这就是导致异常的原因。不要修改您在循环内循环的集合。同样地样品”。我了解我要重新构建此方法并收到以下建议。

ListIterator<Order> it = orders.listIterator();

while ( it.hasNext() ) {
      Order ord = it.next();

      if ( ) // some condition
        it.remove(); // This wil remove the element that we just got using the next() method
      if ( ) // some other condition
        it.add(new Order()); // THis inserts the element immediately before the next call to next()
}

现在我被困在如何在使用迭代方法时添加样本和顺序,因为你会通过一个集合进行不同的迭代,我假设我会使用 for 循环。

这是我对如何更改以不获取 java.util.ConcurrentModificationException 感到困惑的部分。

f

到目前为止,我已经到了这里。

  java.util.ListIterator<Order> it = orders.listIterator();
  while (it.hasNext()) {
     it.next().getId();
     if (sampleOrderMap.containsKey((it.next().getId())))
     {
        Set<OrderSample> samples = sampleOrderMap.get(it.next().getId());

     }

  }`

我只是不知道如何以不会得到 ConcurrentModificationException 的方式放入其余部分

4

1 回答 1

2

来自 Java 文档:

当不允许这样的修改时,检测到对象的并发修改的方法可能会抛出 ConcurrentModificationException。例如,通常不允许一个线程在另一个线程对其进行迭代时修改 Collection。一般来说,在这些情况下,迭代的结果是不确定的。如果检测到此行为,某些迭代器实现(包括 JRE 提供的所有通用集合实现的那些)可能会选择抛出此异常。这样做的迭代器被称为快速失败迭代器,因为它们快速而干净地失败,而不是在未来不确定的时间冒着任意的、非确定性的行为的风险。

请注意,此异常并不总是表示对象已被不同的线程同时修改。如果单个线程发出一系列违反对象约定的方法调用,则该对象可能会抛出此异常。例如,如果线程在使用快速失败迭代器迭代集合时直接修改了集合,则迭代器将抛出此异常。

请注意,不能保证快速失败的行为,因为一般来说,在存在不同步的并发修改的情况下,不可能做出任何硬保证。快速失败操作会尽最大努力抛出 ConcurrentModificationException。因此,编写一个依赖此异常来确保其正确性的程序是错误的:ConcurrentModificationException 应该仅用于检测错误。

要解决此问题,您可以创建一个临时集合以添加到您正在迭代的集合之外。

然后,完成迭代后,您可以使用 orders.AddAll(tempCollection) 添加新项目。

于 2013-10-29T17:01:04.477 回答