iterator抛concurrentmodificationexception是因为其fail-fast机制:modcount被修改后检查失败即抛异常;copyonwritearraylist通过快照避免该异常但写性能差;加锁或concurrenthashmap弱一致性迭代器是替代方案。

为什么 Iterator 在多线程下会抛 ConcurrentModificationException
Java 中大多数集合类(如 ArrayList、HashMap)的 Iterator 是「快速失败」(fail-fast)的。它内部维护一个 modCount 计数器,每次结构修改(增/删)都会更新;而 Iterator 在 next() 或 hasNext() 时会检查该值是否被意外改动——一旦发现不一致,立刻抛出 ConcurrentModificationException。这不是“崩溃”,而是显式中断,防止读到脏数据或进入不可预测状态。
用 CopyOnWriteArrayList 替代普通 ArrayList 迭代
适用于读多写少、迭代频繁但修改极少的场景(比如监听器列表)。它的 iterator() 返回的是创建时刻的数组快照,后续写操作不影响当前迭代器。
-
CopyOnWriteArrayList的add()/remove()会复制整个底层数组,写性能差,别在高频修改场景用 - 迭代器不支持
remove()(调用会抛UnsupportedOperationException) - 不能解决「多个线程同时遍历 + 同时写」导致的逻辑不一致问题,只是避免异常
List<string> list = new CopyOnWriteArrayList();
list.add("a");
list.add("b");
Iterator<string> it = list.iterator(); // 快照已生成
list.add("c"); // 不影响 it
while (it.hasNext()) System.out.println(it.next()); // 输出 a, b</string></string>
加锁:用 synchronized 包裹迭代和修改逻辑
最直接可控的方式,适用于你明确知道哪些代码块需要互斥访问同一集合。
- 必须确保所有对集合的读(含
iterator())、写操作都走同一把锁,否则无效 - 锁对象建议用集合本身(如
synchronized(list) { ... }),避免用this或新对象导致锁错位 - 迭代过程持有锁时间越长,吞吐越低;若需长时间处理单个元素,考虑先复制关键数据再释放锁
List<string> list = new ArrayList();
// ...
synchronized(list) {
Iterator<string> it = list.iterator();
while (it.hasNext()) {
String s = it.next();
// 处理 s,尽量轻量;重逻辑移出 synchronized 块
}
}</string></string>
改用线程安全的迭代方式:ConcurrentHashMap 的 keySet().iterator()
ConcurrentHashMap 的迭代器是弱一致性(weakly consistent)的:不抛 ConcurrentModificationException,可容忍并发修改,但不保证反映某一时刻的完整快照。
- 仅适用于
ConcurrentHashMap,不适用于ConcurrentLinkedQueue等其他并发集合(它们的迭代器行为各异) - 迭代中可能跳过刚插入的元素,也可能重复看到刚删除又被 rehash 的元素——业务上能接受这种宽松语义才用
- 不要依赖
size()或isEmpty()与迭代结果严格一致
ConcurrentHashMap<string integer> map = new ConcurrentHashMap();
map.put("a", 1);
Iterator<string> it = map.keySet().iterator(); // 安全
while (it.hasNext()) {
String key = it.next(); // 可能看不到后续 put 的 key
map.put("b", 2); // 不影响当前迭代
}</string></string>
真正麻烦的不是异常本身,而是误以为加个 try-catch 就算兜住了——ConcurrentModificationException 是设计信号,提示你存在未受控的并发访问。选方案前先确认:修改频率高不高?迭代期间能否容忍旧数据?要不要强一致性?这些比“怎么不让它崩”更重要。










