fail-fast是java集合框架中一种快速失败的错误检测机制,通过modcount与expectedmodcount比对,在迭代中检测到结构性修改时立即抛出concurrentmodificationexception,用于暴露“边遍历边修改”类bug,而非保障线程安全。

fail-fast 是 Java 集合框架中一种用于**及时暴露结构性修改错误**的检测机制,不是用来保证线程安全的,而是帮开发者快速发现“边遍历边乱改集合”这类 bug。
它怎么工作的?
核心靠两个计数器配合:
- modCount:集合内部维护的“修改次数计数器”,每次调用 add、remove、clear 等改变结构的方法,它就 +1;
- expectedModCount:迭代器创建时,把当时的 modCount 值“快照”下来,存在自己内部;
- 每次调用 next() 或 remove() 前,迭代器都会比对:如果 modCount ≠ expectedModCount,立刻抛出 ConcurrentModificationException。
哪些操作会触发它?
只要在迭代过程中,用集合自身的方法增删元素(哪怕单线程),就可能触发:
- foreach 循环里写 list.add(x) 或 list.remove(x);
- Iterator 遍历时,调用 list.remove(x),而不是 iterator.remove();
- 多线程下,一个线程在遍历,另一个线程调用了 add/remove。
哪些情况它不报错?
不是所有修改都敏感,也不是所有场景都一定报错:
- 只改元素内容(如 list.set(0, "new"))不会影响 modCount,不触发;
- 用迭代器自己的 remove() 方法删除,它会同步更新 expectedModCount,所以合法;
- fail-fast 不是同步机制,modCount 变更无可见性保障,所以“可能报错”,但不能依赖它来控制逻辑。
该怎么避免异常?
真要边遍历边改,有更稳妥的做法:
- 删元素优先用 iterator.remove();
- 需要增/删多个,先收集待操作元素,遍历完再统一处理;
- 多线程场景,换用 CopyOnWriteArrayList 或 ConcurrentHashMap 这类 fail-safe 集合。











