fail-fast 与 fail-safe 机制
面试官问:"在遍历 ArrayList 时,如果同时修改,会发生什么?"
候选人小杜答:"会抛出 ConcurrentModificationException。"
面试官点点头:"为什么?"
小杜说:"因为 modCount 和 expectedModCount 不一致。"
面试官追问:"那怎么正确地在遍历时删除元素?"
小杜说:"用 Iterator.remove()..."
面试官追问:"除了 Iterator,还有别的方法吗?"
小杜答不上来。
【面试官心理】 这道题考的是候选人对 Java 并发集合迭代器机制的理解深度。能说出 modCount 机制和三种正确遍历删除方式的候选人,说明对并发编程有一定积累。
一、fail-fast 机制 🔴
1.1 ConcurrentModificationException
1.2 modCount 机制
1.3 为什么要 fail-fast
⚠️
fail-fast 不是线程安全机制,它只是检测"非预期的并发修改"。在单线程中使用 for-each 遍历时手动删除,也会触发 fail-fast。
二、fail-safe 机制 🔴
2.1 什么是 fail-safe
fail-safe:遍历的是集合的快照,修改不影响遍历。
2.2 fail-safe vs fail-fast 对比
三、正确遍历删除的三种方式 🔴
3.1 使用 Iterator.remove()
3.2 使用 removeIf()(JDK 9+)
3.3 倒序遍历
四、ConcurrentHashMap 的 fail-safe 🟡
五、追问升级
面试官:"ConcurrentHashMap 的迭代器和 HashMap 的迭代器有什么区别?"
【面试官心理】 能说出 ConcurrentHashMap 迭代器"弱一致性"特性的候选人,说明对并发集合有深入理解。这是 P6+ 的要求。