Java Collection中的fast-fail机制

本文详细介绍了Java集合中Iterator的Fail-Fast机制,包括其定义、触发条件及原理。解释了如何通过modCount和expectedModCount变量检测并避免并发修改错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

部分内容参考自:http://www.cnblogs.com/skywang12345/p/3308762.html

  • fail-fast 定义

fail-fast(快速失败)机制:是Java集合中Iterator的一种检错机制。

当某个线程用iterator对list进行遍历时,其他线程同时并发的对list进行插入或者删除等操作,使得list产生了结构性的变化(结构性变化是指:list的size被改变的一些变化),就会抛出ConcurrentModificationException,Iterator产生fail-fast行为,使自己快速失效,以避免自己去冒险,去经历未来不确定时刻的不确定因素,这也是fail-fast机制的目的。

注意1,只有add,remove,clear等操作能使得list的size发生改变,而set等操作没有使得list的size产生变化,因此,只有前者的相关操作可以使得list产生结构性的变化。

注意2,并非所有插入删除等操作都能产生fail-fast行为。如果使用Iterator内部的插入删除就不会,原因见后。除此之外都能产生fail-fast行为。

举个例子:当线程A正在用iterator遍历list时,线程B同时用LinkedList中的add()并发的向list中插入了元素,使得list产生了结构性的改变,这时会抛出ConcurrentModificationException,Iterator失效。

  • fail-fast 原理

fail-fast的原理基于两个变量 modCount 和 expectedModCount ,首先介绍一下modCount变量:

在AbstractList中定义了一个非static的全局变量modCount(一个对象拥有一个该变量),AbstractList的子类自然也会拥有自己的modCount,比如:ArrayList,LinkedList,Vector等都是该类的子类。当某个集合产生了结构性的变化时,该集合所持有的modCount就会加一。Iterator类中的add()等方法也会使modCount加一。

接下来是expectedModCount变量:

expectedModCount变量是定义在每个子类的内部类ListIterator中的,当Iterator被创建后,expectedModCount初始化为modCount。这里需要注意的是,expectedModCount值不是一成不变的。当调用Iterator中的插入删除等方法改变了list的size时,expectedModCount值会同modCount值一起加一,与modCount值保持一致。而调用外部类的插入删除等方法时,就只有modCount值会加一,expectedModCount值就不变,这两个变量就不相等了。

fail-fast的原理:

在调用iterator中的next(),previous()等方法时,首先会去比较一下当前modCount和expectedModCount值,如果这两个值不相等,说明:在遍历期间,有其他线程修改了正在遍历的这个集合,并使得该集合产生了结构性的变化,而且Iterator并不知道其他线程都对list做了哪些修改,这个对Iterator来说是很危险的。故,这个时候就该抛ConcurrentModificationException异常,Iterator产生了fail-fast行为,使自己快速失效。这也就说明了为什么Iterator内部的插入删除操作不会产生fail-fast行为,因为这些修改过程是Iterator知道的,它能在修改的过程中去修改一些指针来使自己能够适应这些修改。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值