专栏首页苦逼的码农谈谈fail-fast与fail-safe

谈谈fail-fast与fail-safe

让写作,成为一种兴趣!

今天,我们来谈谈fail-fast与fail-safe是什么以及工作机制。

fail-fast是什么?

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

下面我们来看看官方文档在HashMap这个集合中,它是怎么解释fail-fast的(如下图):

意思就是说,当Iterator这个迭代器被创建后,除了迭代器本身的方法(remove)可以改变集合的结构外,其他的因素如若改变集合的结构,都被抛出ConcurrentModificationException异常。

请在继续看官方的描述:

意思就是说:迭代器的快速失败行为是不一定能够得到保证的,一般来说,存在非同步的并发修改时,不可能做出任何坚决的保证的。但是快速失败迭代器会做出最大的努力来抛出ConcurrentModificationException。因此,编写依赖于此异常的程序的做法是不正确的。正确的做法应该是:迭代器的快速失败行为应该仅用于检测程序中的bug.

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

解释下“结构”

这里,我解释下什么是结构上的改变。例如集合上的插入和删除就是结构上的改变,但是,如果是对集合中某个元素进行修改的话,并不是结构上的改变哦。

下面,我们来演示下在单线程的环境下,fail-fast抛出异常的实例:

打印结果:

结果分析:因为当temp==3的时候,执行list.remove()方法,集合的结构被改变了,所以再次遍历迭代器的时候,就会抛出异常。

fail-fast的工作原理

我们首先先来看下源码:

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

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

什么时候modCount会发生改变呢?

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

fail-fast的一些处理方法

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

Collections.synchronizedList来解决。

误区

fail-fast就先讲到这里,下面简单讲讲fail-safe与fail-fast的区别

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

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

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

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

本文分享自微信公众号 - 苦逼的码农(di201805),作者:小秋

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-05-29

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 从本质上搞懂头痛的乱码问题!

    字符集 和 编码无疑是IT菜鸟甚至是各种大神的头痛问题。当遇到纷繁复杂的字符集,各种火星文和乱码时,问题的定位往往变得非常困难。本文将会从原理方面对字符集和编码...

    帅地
  • 什么是并查集?有哪些应用?

    并查集可以看作是一个数据结构,如果你根本没有听说过这个数据结构,那么你第一眼看到 “并查集” 这三个字的时候,脑海里会浮现一个什么样的数据结构呢?

    帅地
  • 必学十大经典排序算法,看这篇就够了(附完整代码/动图/优质文章)(修订版)

    十大排序算法可以说是每个程序员都必须得掌握的了,花了一天的时间把代码实现且整理了一下,为了方便大家学习,我把它整理成一篇文章,每种算法会有简单的算法思想描述,为...

    帅地
  • python df遍历的N种方式

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    多凡
  • 排序算法之希尔排序-Java版

    希尔排序是加强版的插入排序,相对与普通的插入排序做了优化,比普通的插入排序多了一个步长的概念

    shengjk1
  • python 集合

    1、定义 集合是一个无序的,不重复的数据组合,它的主要作用如下: 去重,把一个列表变成集合,就自动去重了; 关系测试,测试两组数据之间的交集,差集,并集等关系。...

    py3study
  • "字符"、"字符集"、"进制"、"编码"、"加密" 这都是啥?

    对于大多数搞安全的来说,应该是能理解上面几个名次的,不过如果我说GBK ,Unicode, UTF-8, GB2312, ISO-xxxx, 二进制,八进制,十...

    意大利的猫
  • 史上最通俗,彻底搞懂字符乱码问题的本质

    那么,对于乱码这个看似不起眼,但并不是一两话能讲清楚的问题,是很有必要从根源了解字符集和编码原理,知其然知其所以然显然是一个优秀码农的基本素养,所以,便有了本文...

    JackJiang
  • 从本质上搞懂头痛的乱码问题!

    字符集 和 编码无疑是IT菜鸟甚至是各种大神的头痛问题。当遇到纷繁复杂的字符集,各种火星文和乱码时,问题的定位往往变得非常困难。本文将会从原理方面对字符集和编码...

    帅地
  • 字符集和字符编码(Charset & Encoding)

    计算机中储存的信息都是用二进制数表示的;而我们在屏幕上看到的英文、汉字等字符是二进制数转换之后的结果。通俗的说,按照何种规则将字符存储在计算机中,如’a’用什么...

    空空云

扫码关注云+社区

领取腾讯云代金券