ConcurrentModificationException的根本原因是fail-fast机制检测到集合被非迭代器方式结构性修改,单线程下调用list.remove()等方法也会触发;必须用iterator.remove()安全删除,或改用CopyOnWriteArrayList等线程安全集合。

Java里Iterator为什么会抛ConcurrentModificationException_原因及规避方案

Java中IteratorConcurrentModificationException,根本原因是快速失败(fail-fast)机制在检测到集合被意外修改时主动中断遍历,不是因为“多线程并发”本身,而是单线程下用非迭代器方式修改了正在遍历的集合——这是最容易被误解的一点。

为什么单线程也会触发?

每个支持迭代的集合(如ArrayListHashMap)内部都有一个modCount(修改计数器),记录结构修改次数。迭代器创建时会把当时的modCount复制为自己的expectedModCount。每次调用next()hasNext()前,都会检查两者是否一致。只要集合被add()remove()clear()等方法结构性修改,modCount就会加1,而迭代器的expectedModCount没变,校验失败就抛异常。

常见“单线程踩坑”场景:

正确删除元素:必须用迭代器自身的remove()

Iterator提供了安全删除方法:仅在调用过next()之后,立刻调用iterator.remove(),它会同步更新expectedModCount,避免异常。

示例:

Iterator it = list.iterator();
while (it.hasNext()) {
    String s = it.next();
    if ("target".equals(s)) {
        it.remove(); // ✅ 安全删除
    }
}

其他规避方案(按推荐顺序)

多线程下的特别注意

即使用了iterator.remove(),在多线程环境下仍不安全:迭代器本身不是线程安全的。两个线程同时遍历+修改,依然可能出错。此时必须:

基本上就这些。核心记住一点:ConcurrentModificationException是集合自我保护的信号,不是bug,而是提醒你——别绕过迭代器直接动集合结构。

本文转载于:互联网 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。