后端面试题:java中什么是快速失败?
在 Java 里,“快速失败”(Fail-Fast)是集合类(像 ArrayList
、HashMap
这类)采用的一种错误检测机制。其核心在于:当一个线程正在遍历集合时,要是发现该集合的结构被其他线程修改了(比如进行了添加、删除操作),它会马上抛出 ConcurrentModificationException
异常,而不是继续进行不确定行为的操作。
实现原理
集合类内部有一个名为 modCount
的计数器,只要集合的结构发生变化,这个计数器的值就会增加。在进行迭代操作时,迭代器会去检查 modCount
的值。如果发现该值和迭代器创建时记录的 expectedModCount
不一样,就会判定集合的结构已经被修改,进而抛出异常。
示例代码
下面这段代码展示了快速失败机制的工作情况:
java
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;public class FailFastExample {public static void main(String[] args) {List<String> list = new ArrayList<>();list.add("apple");list.add("banana");list.add("cherry");Iterator<String> iterator = list.iterator();while (iterator.hasNext()) {String element = iterator.next();System.out.println(element);// 下面这行代码会触发 ConcurrentModificationException 异常list.add("date"); }}
}
在这个例子中:
- 我们先创建了一个
ArrayList
并往里面添加了三个元素。 - 接着获取该集合的迭代器。
- 在使用迭代器遍历集合的过程中,尝试向集合里添加一个新元素。
- 这就会使迭代器检测到
modCount
发生了变化,从而抛出ConcurrentModificationException
异常。
注意要点
- 多线程环境:快速失败机制并不能提供线程安全保障,它只是用于尽早地发现错误。若要在多线程环境下安全地使用集合,可以考虑使用
CopyOnWriteArrayList
或者ConcurrentHashMap
这类支持并发操作的集合类。 - 单线程情况:在单线程环境中,如果在迭代过程中调用集合自身的方法(像
add()
、remove()
)去修改集合结构,也会触发快速失败机制。若要在迭代时修改集合,应该使用迭代器自身提供的remove()
方法。 - 不保证一定触发:快速失败机制只是尽力去检测并发修改的情况,并没有严格的保证。所以,不能把它当作一种通用的并发控制策略来使用。
快速失败机制主要是为了帮助开发者快速找出程序中可能存在的并发修改问题,它在迭代器的设计中被广泛应用。