具体原因请参考下方链接博客,此文章仅为我个人的简要总结笔记。
ArrayList的remove()方法:会导致list的modCount加一,从而跟iterator的expectedModCount不一致,抛出异常:
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
注意,像使用for-each进行迭代实际上也会出现这种问题。只要在next()或remove()之前有对集合操作的动作,从而导致modCount发生了改变,都会抛那个并发修改异常的。
而Itr类的的remove()方法,多了一句:
expectedModCount = modCount; 所以不会报错。
也就是说,在迭代时,只能用迭代器的remove()。
public void remove() {
if (lastRet == -1)
throw new IllegalStateException();
checkForComodification();
try {
AbstractList.this.remove(lastRet);
if (lastRet < cursor)
cursor--;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException e) {
throw new ConcurrentModificationException();
}
}
那么,在多线程环境下,我们如何应对这个问题呢?
1)用Collections.synchronizedCollection() 去同步集合, 但是这样可能会影响效率;
2)CopyOnWriteArrayList这个集合迭代的时候可以对集合进行增删操作, 因为迭代器中没有checkForComodification。
博客园——Java ConcurrentModificationException异常原因和解决方法
CSDN——集合迭代时对集合进行修改抛ConcurrentModificationException原因的深究以及解决方案