迭代ArrayList <integer> </integer>时出现ConcurrentModificationException

时间:2012-05-05 23:15:49

标签: java

我试图遍历整数ArrayList并获取每个元素的值,但我在int值得到错误= ....

不确定是什么时候发生的。请指教。

Iterator<Integer> listItr = executeList.iterator(); // iterator for the execute list 
    while (listItr.hasNext()) { // iterate through list and do work!
        int robIndex = listItr.next();
        int timer = fakeRob.exeCountDown(robIndex); // decrement first then return timer
        if (timer == 0) {// check if instr finished execution
            System.out.println("timer expired. fire");
            executeList.remove(executeList.indexOf(robIndex)); // 1. remove instr from exeList
            transitState(robIndex, EX, WB); // 2. transit from EX state to WB state
            int tag = fakeRob.getTag(robIndex); // get producer tag
            regFile.setRdy(tag); // 3a. set register file ready flag for this tag
            fakeRob.wakeUp(tag); // 3b. wake up instructions with this tag
        }
    }

错误:

java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
at java.util.AbstractList$Itr.next(AbstractList.java:343)
at sim.execute(sim.java:180)
at sim.<init>(sim.java:71)
at sim.main(sim.java:270

谢谢,

汉克

2 个答案:

答案 0 :(得分:1)

如果局部变量值是你“做一些东西”的事情,并且你没有修改列表,那么当你在那里时,一些外部线程正在修改列表。

否则,see the link provided by @edalorozo for some ideas

编辑添加

我从不使用iterator.remove()成语,因为我从未完全熟悉迭代器的习语。并且总是将它与短暂的和实现不佳的Enumerator东西混在一起。在增强的for循环之前,我通常使用非常老式的for (int i-0; i<foo.length; i++)样式进行循环。并非所有迭代器都支持remove(),那么重点是什么?

因此,即使我现在使用增强的for循环,我也“习惯”“收集所有东西并将其删除”。在您的代码中,那将是:

ArrayList <Integer> toBeRemoved = new ArrayList <Integer>();
for (Integer robIndex : executeList) {
   // note, I distrust auto-unboxing, (see all the Java Puzzlers books!)
   // so I'd probably add an explicit unbox here
   int robIndexi = robIndex.intValue();

   int timer = fakeRob.exeCountDown(robIndexi); // decrement first then return timer
   if (timer == 0) {// check if instr finished execution
      toBeRemoved.add(robIndex);
      // all that other stuff here...
   }
}

// remove everything now
executeList.removeAll(toBeRemoved);

答案 1 :(得分:1)

也许如果你把你正在做的事情放在循环中它会有所帮助。如果您尝试从列表中删除元素,则需要调用listItr.remove()来执行此操作。通常,您不应该在循环中调用任何修改列表的函数(即add(),set()等等。)。

以下代码会触发此

Iterator<Integer> it = executeList.iterator();
while (it.hasNext()) {
  Integer i = it.next();
  executeList.remove(i);
}

正确的方法是:

Iterator<Integer> it = executeList.iterator();
while (it.hasNext()) {
  Integer i = it.next();
  it.remove();
}

其他线程(如上所述)也可能是问题所在。请记住,迭代器由所有java提供的集合中的列表本身支持。因此,如果另一个线程在您迭代时修改了列表,那么您将遇到此问题。