fail-fast & fail-safe
先放一篇大佬的文章:一文彻底弄懂fail-fast、fail-safe机制(带你撸源码) - 知乎
在学习Java的ArrayDeque原理实现的时候,查的资料里出现了fail-fast。
fail-fast就是一种错误检测机制,一旦检查到可能有错误就马上抛出异常,程序不再往下进行。
public User queryUserById(String userId) {
if(userId == null || ("").equals(userId)) {
throw new RuntimeException("error userId"); // 抛出异常 结束程序
}
// 程序其他部分
}
ArrayDeque的迭代器也被设计为fail-fast。
所以Java的java.util 包下的集合类都是快速失败的,因此他们都是非同步的,不能在多线程下进行并发修改(比如在AB两进程下同时操作一个集合,一个线程对其中的元素进行了修改,导致该集合的modCount值被改变,另一个线程就会检测到modCount != expectedmodCount这一条件满足,就会抛出Concurrent Modification Exception异常而立刻终止遍历)。
*注意:如果在集合元素发生改变时,被修改过的modCount值恰好也是满足 modCount == exceptedmodCount这一条件的,则不会触发快速失败。
Java中同时还有另一种检测机制——fast-safe,也就是遍历集合时,并不是对原集合本身进行遍历,而是对其拷贝进行遍历。所以采用安全失败机制的集合容器是线程安全的,可以同时在多个线程中对同一集合进行操作。
*注意:安全失败机制避免了多线程中可能出现的异常,但正因如此,迭代器无法感知到在迭代过程中原集合发生的改变。