如何避免并发修改集合时引发的 ConcurrentModificationException,通过变量快照分析解决?
- 内容介绍
- 相关推荐
本文共计939个文字,预计阅读时间需要4分钟。
在多线程环境下遍历集合时抛出`ConcurrentModificationException`,根本原因不是并发修改本身,而是因为迭代器内部维护的`modCount(修改计数)`快速照相机机制失效。它本质上是一个单线程安全检测机制,误用于多线程环境后,暴露了设计局限。
modCount 快照机制如何工作
ArrayList、HashMap 等非线程安全集合在结构变更(add/remove/resize)时会递增自身 modCount 字段;而每个迭代器(如 ArrayList.Itr)在创建时会复制该值为 expectedModCount。每次调用 next() 或 remove() 前,都会检查二者是否一致:
- 一致 → 继续迭代
- 不一致 → 抛出
ConcurrentModificationException
这个检查发生在单次迭代操作入口处,不涉及锁或内存屏障,纯粹是“事后校验”。它无法区分:是其他线程改了集合?还是本线程在迭代中途自己调用了 list.remove()?——都算“非法修改”。
本文共计939个文字,预计阅读时间需要4分钟。
在多线程环境下遍历集合时抛出`ConcurrentModificationException`,根本原因不是并发修改本身,而是因为迭代器内部维护的`modCount(修改计数)`快速照相机机制失效。它本质上是一个单线程安全检测机制,误用于多线程环境后,暴露了设计局限。
modCount 快照机制如何工作
ArrayList、HashMap 等非线程安全集合在结构变更(add/remove/resize)时会递增自身 modCount 字段;而每个迭代器(如 ArrayList.Itr)在创建时会复制该值为 expectedModCount。每次调用 next() 或 remove() 前,都会检查二者是否一致:
- 一致 → 继续迭代
- 不一致 → 抛出
ConcurrentModificationException
这个检查发生在单次迭代操作入口处,不涉及锁或内存屏障,纯粹是“事后校验”。它无法区分:是其他线程改了集合?还是本线程在迭代中途自己调用了 list.remove()?——都算“非法修改”。

