fail-fast 机制

今天偶然听到同事提起fail-fast机制,也说这是所有程序员都会碰到的一个问题,but非常尴尬的就是我真的没有碰到过,也觉得自己好像真的是井底之蛙,很多很多知识点都不知道。当然,我也觉得,一个人除了主动学习之外,其他的知识点都是要通过日常碰到来进行解决以及学习。今天既然听到了,当然必须来进行一下学习。

首先贴出代码块,fail-fast可能发生在单线程环境下,或者多线程环境下。

我们先列出单线程环境下可能出现的一种场景。

单线程环境下fail-fast

运行后产生的结果如下


单线程环境下产生fail-fast

多线程环境下


多线程环境下fail-fast

运行后产生结果如下


多线程环境下产生fail-fast

首先我们看异常信息,concurrentModficationException,顾名思义,并发修改异常,而异常发生的地方在ArrayList的匿名类Itr.next方法中的checkForComodification处。其实通过两个不同的例子我们可以发现,其中最主要的原因就是进行了remove操作,而为什么做了remove之后就会产生这样的快速失败呢。

根据以上信息,我找到了对应抛出异常的代码段,进行分析。如下图所示。

checkForComodification异常代码段

根据代码段中,我们可以看到抛出异常的主要原因就是modCount 与 expectedModCount不一致了,进而导致出现了并发修改异常,那么这两个值到底是什么东西呢?这就要向上追溯,看下ArrayList中的Itr匿名类对这两个属性的定义了。

那么在这里我也解释一下itr类是个什么东西,其实它就是由ArrayList自己所实现的Iterator,而我们在使用Iterator时,ArrayList会返回给我们一个自己实现的Itr内部类,这个内部类包含了ArrayList自己所实现的遍历数组方法。也就是在这里,发生了异常。放出源码。

Itr中属性定义

通过初始化我们可以发现,expectedModCount就是ArrayList中的modCount,那这个modCount其实读过ArrayList源码的人都知道这个值是什么,但是可能有些小白真的没有见过,所以我们也拉出源码看一下。


remove的modCount


clear的modCount


add的modCount

在这我找到了最常见的三处修改modCount的地方,remove,clear,add的三个操作都对其modCount进行了加一操作,当然,不止这三处对modCount进行增加,还有很多地方的操作都会使其加一,值进行改变。也就是说,modCount记录了这个ArryList的变动次数,当list进行了某些修改内容的操作后,便会记录这一次的值。

我们再返回头去看错误处其实就很清晰了,我们因为在线程或者遍历中,对数组进行了remove操作,而只要执行了remove,就会使modcount加一,导致最初被赋值的exctepModCount与当前数组的modCount不一致了,那么在遍历过程中,itr都会先进行check,在check时发现这两个值不一致了,所以会产生concurrentModficationException这样的并发修改异常。


哈哈哈没想到吧,在结尾处我胡汉三又回来了,2020.4.24我参加了一个面试,被对方问起了fail-fast,以此考验我对这个知识点了解是否深刻。我真儿真儿没想到真的有如此棒的面试官会去翻阅我的博客,感到荣幸至极哈哈。

不过啊,我也通过面试官的询问,发现了自己对这个机制还有未了解清晰的地方与内容,在此再次感激技术官的提问,使我知道自己的不足之处。

面试官提问:

(1)既然你说modcount是控制是否扔出异常的,那for循环的时候做add操作是否也会抛出异常呢。

当然对于这个问题我肯定是不清晰的,我是回复说不会的,但是反观既然我add时候会修改modcount,那岂不是在for循环时add也会抛出fail-fast???知道自己答错了,但也没想出到底是为什么。后续进行查询发现大错特错哈哈哈哈,感谢面试官。

首先我们要知道iterator与普通for循环的区别。

iterator是通过容器自己实现的内部类,我们想做迭代操作就必须获取相应容器实现的itr对象,再通过其内部实现去迭代数据元素。而for循环是针对底层数组下标直接进行操作。故此,对于普通的for循环进行add操作并不会去检查相应的modcount是否发生了变动。相对的,itr自己内部实现了容器迭代的逻辑,在容器循环过程中一旦发生了add、remove、等使modcount发生变动的操作时,便会抛出fail-fast异常。这种小细节只能怪自己没有认真思考与阅读,不能去怪任何人,反而要感激他人的提问。

(2)fail-fast在单线程环境下是否会产生。

这个答案我也回答错误了,当时认为单线程中不会有这样的错误抛出,实际上并不是这样的。

即使在单线程环境下,我们在利用iterator进行迭代的时候也会相应的改变其modcount指针,这个数值一旦被改变了,对于其他需要checkmodcount的方法来说,都会产生fail-fast异常。并不单单是在多线程环境下会产生这样的错误。


checkForComodifacation

文章是小编辛辛苦苦敲出来的,拿走的记得标明原作者哦。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,294评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,780评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,001评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,593评论 1 289
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,687评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,679评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,667评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,426评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,872评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,180评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,346评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,019评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,658评论 3 323
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,268评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,495评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,275评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,207评论 2 352

推荐阅读更多精彩内容