Fail-fast和Fail-safe

220 阅读2分钟

Fail-fast和Fail-safe

定义

fail-fast的字面意思是“快速失败”。当我们在遍历集合元素的时候,经常会使用迭代器,但在迭代器遍历元素的过程中,如果集合的结构被改变的话,就会抛出异常,防止继续遍历。这就是所谓的快速失败机制。

fail-fast,即快速失败机制,它是java集合中的一种错误检测机制,当多个线程(当个线程也是可以滴),在结构上对集合进行改变时,就有可能会产生fail-fast机制。

原理

从源码我们可以发现,迭代器在执行next()等方法的时候,都会调用checkForComodification()这个方法,查看modCount==expectedModCount?如果相等则抛出异常。

expectedModcount:这个值在对象被创建的时候就被赋予了一个固定的值modCount。也就是说这个值是不变的。也就是说,如果在迭代器遍历元素的时候,如果modCount这个值发生了改变,那么再次遍历时就会抛出异常。

时机

这次就不带大家看源码了。其实当我们对集合的元素的个数做出改变的时候,modCount的值就会被改变,如果删除,插入。但修改则不会。

解决

如果我们不希望在迭代器遍历的时候因为并发等原因,导致集合的结构被改变,进而可能抛出异常的话,我们可以在涉及到会影响到modCount值改变的地方,加上同步锁(synchronized),或者直接使用Collections.synchronizedList来解决。

fail-safe

当我们对集合结构上做出改变的时候,fail-fast机制就会抛出异常。但是,对于采用fail-safe机制来说,就不会抛出异常(大家估计看到safe两个字就知道了)。

这是因为,当集合的结构被改变的时候,fail-safe机制会在复制原集合的一份数据出来,然后在复制的那份数据遍历。

因此,虽然fail-safe不会抛出异常,但存在以下缺点

  1. 复制时需要额外的空间和时间上的开销。
  2. 不能保证遍历的是最新内容。