ConcurrentModificationException 异常发生原因
首先 ConcurrentModificationException 是在遍历时发生的.
背景知识:
- 遍历分为
fori
,foreach
,iterator
三种方式 -
fori
在删除 / 新增元素时, 多线程下可能导致数组索引越界 / 数据混乱 (因为索引对不上) -
foreach
,iterator
可能导致ConcurrentModificationException
- 集合使用
foreach
底层本质上是调用的iterator
ConcurrentModificationException
异常原因有两种情况 (本质上的逻辑都是checkForComodification(), 即比较 list.modCount == itr.expectedModCount
):
- 单线程下
foreach
/iterator
遍历时, 使用list.remove()
会抛出异常 (modCount
被修改, 但是expectedModCount
还是旧值, 抛出异常) -
- 多线程下
foreach
/iterator
遍历时, 使用iterator.remove()
可能会抛出异常 (虽然iterator.remove()
方法会重新把expectedModCount
的值复制给modCount
. 但是存在线程安全问题. 在iterator.next()
方法时, 还会校验modCount == expectedModCount
, 不等则抛出异常)