不不不!
在单个威胁任务中,您不需要使用 Iterator,此外,CopyOnWriteArrayList(由于性能下降)。
解决方案要简单得多:尝试使用规范的 for 循环而不是 for-each 循环.
根据 Java 版权所有者(几年前是 Sun,现在是 Oracle)for-each loop guide 的说法,它使用迭代器遍历集合并隐藏它以使代码看起来更好。但是,不幸的是,正如我们所看到的,它产生的问题多于利润,否则就不会出现这个话题。
例如,在修改后的 ArrayList 上进入下一次迭代时,这段代码将导致 java.util.ConcurrentModificationException:
// process collection
for (SomeClass currElement: testList) {
SomeClass founDuplicate = findDuplicates(currElement);
if (founDuplicate != null) {
uniqueTestList.add(founDuplicate);
testList.remove(testList.indexOf(currElement));
}
}
但是下面的代码工作得很好:
// process collection
for (int i = 0; i < testList.size(); i++) {
SomeClass currElement = testList.get(i);
SomeClass founDuplicate = findDuplicates(currElement);
if (founDuplicate != null) {
uniqueTestList.add(founDuplicate);
testList.remove(testList.indexOf(currElement));
i--; //to avoid skipping of shifted element
}
}
因此,尝试使用索引方法迭代集合并避免 for-each 循环,因为它们不等价!
For-each 循环使用一些内部迭代器,这些迭代器检查集合修改并抛出 ConcurrentModificationException 异常。要确认这一点,请仔细查看使用我发布的第一个示例时打印的堆栈跟踪:
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
at java.util.AbstractList$Itr.next(AbstractList.java:343)
at TestFail.main(TestFail.java:43)
对于多线程,使用相应的多任务方法(如 synchronized 关键字)。