快速失败是指某个线程在迭代集合类的时候,不允许其他线程修改该集合类的内容,这样迭代器迭代出来的结果就会不准确。

比如用iterator迭代collection的时候,iterator就是另外起的一个线程,它去迭代collection,如果此时用collection.remove(obj)这个方法修改了collection里面的内容的时候,就会出现ConcurrentModificationException异常,这时候该迭代器就快速失败。

代码如下:

package com.vino.assemble;

import java.util.ArrayList;
import java.util.List; /**
* show fail fast in in the hashmap
* @author haowei.yu
*
*/
public class FailFastDemo {
public static void main(String[] args) {
List<Integer> tempList = new ArrayList<Integer>();
tempList.add(1);
tempList.add(2);
tempList.add(3);
tempList.add(4);
tempList.add(5);
tempList.add(1); //use iterator to travel the list and remove the value equals to 1 for(int temp: tempList){
if(temp == 1){
tempList.remove(temp);
}
}
}
}

这样运行程序,就会抛出java.util.ConcurrentModificationException异常。

这样做的好处是:对于非并发集合,在用迭代器对其迭代时,若有其他线程修改了增减了集合中的内容,这个迭代会马上感知到,并且立即抛出 ConcurrentModificationException 异常,而不是在迭代完成后或者某些并发的场景才报错。具体这样的机制在java里是怎么实现的呢?其实很简单,是通过modCount域来实现的。modCount顾名思义是修改次数,对List内容的修改都会增加这个值,在迭代器初始化的过程中会将这个值赋值给迭代器的expectedModCount。我们来看ArrayList和Iterator的源码,注释已经写的听清楚了,这里就不解释了。

//ArrayList的源码
protected transient int modCount = 0; //In AbstractList class,provider fail-fast iterators.note that this field is transient public boolean add(E e) {
modCount++; // Increments modCount!!
.....
return true;
} public E remove(int index) {
....
modCount++; // Increments modCount!!
....
return oldValue;
} //Iterator的源码 int expectedModCount = modCount; // iterator believes the backing list should hava.
public void remove() {
try {
....
if (modCount != expectedModCount)// judge the modCount equals with expectedModCount.
throw new ConcurrentModificationException();
...
}
}

TIPS:

  • 在迭代器创建之后,如果从结构上对映射进行修改,除非通过迭代器本身的 remove 方法,其他任何时间任何方式的修改,迭代器都将抛出ConcurrentModificationException。
  • 迭代器的快速失败行为不能得到保证,一般来说,存在非同步的并发修改时,不可能作出任何的保证。快速失败迭代器只是尽最大努力抛出ConcurrentModificationException。因此,编写依赖于此异常的程序的做法是错误的,正确做法是:迭代器的快速失败行为应该仅用于检测程序错误。

arrayList里的快速失败的更多相关文章

  1. 集合迭代器快速失败行为及CopyOnWriteArrayList

    以下内容基于jdk1.7.0_79源码: 什么是集合迭代器快速失败行为 以ArrayList为例,在多线程并发情况下,如果有一个线程在修改ArrayList集合的结构(插入.移除...),而另一个线程 ...

  2. Java笔记-快速失败and安全失败

    参考资料:http://blog.csdn.net/chenssy/article/details/38151189 快速失败 fail-fast 安全失败 fail-safe java.util包下 ...

  3. (简单易懂)Java的快速失败(fail-fast)与安全失败,源码分析+详细讲解

    之前在程序中遇到快速失败的问题,在网上找解释时发现网上的问题总结都比较片面,故打算自己总结一个,也可以供以后参考. --宇的季节 首先什么是快速失败? 快速失败是为了提示程序员在多线程的情况下不要用线 ...

  4. 关于java中ArrayList的快速失败机制的漏洞——使用迭代器循环时删除倒数第二个元素不会报错

    一.问题描述 话不多说,先上代码: public static void main(String[] args) throws InterruptedException { List<Strin ...

  5. java ArrayList 迭代器快速失败源码分析

    先来看一个例子: @Test void test2() { ArrayList<String> list = new ArrayList<String>(); list.add ...

  6. 【1】ConcurrentModificationException 异常解析和快速失败,安全失败

    目录 一.引起异常的代码 二.foreach原理 三.从ArrayList源码找原因 四.单线程解决方案 五.在多线程环境下的解决方法 一.引起异常的代码 以下三种的遍历集合对象时候,执行集合的rem ...

  7. 快速失败机制--fail-fast

    fail-fast 机制是Java集合(Collection)中的一种错误机制.当多个线程对同一个集合的内容进行操作时,就可能会产生fail-fast(快速失败)事件.例如:当某一个线程A通过iter ...

  8. 快速失败(fail-fast)和安全失败(fail-safe)的区别

    1.fail-fast和fail-safe比较 Iterator的安全失败是基于对底层集合做拷贝,因此,它不受源集合上修改的影响.java.util包下面的所有的集合类都是快速失败的,而java.ut ...

  9. Java SE之快速失败(Fast-Fail)与快速安全(Fast-Safe)的区别[集合与多线程/增强For](彻底详解)

    声明 特点:基于JDK源码进行分析. 研究费时费力,如需转载或摘要,请显著处注明出处,以尊重劳动研究成果:博客园 - https://www.cnblogs.com/johnnyzen/p/10547 ...

随机推荐

  1. 快速进入pycharm图形界面

    解压后的pycharm相关文件的路径:/home/hadoop2/下载/pycharm-community-4.5.4 添加快速启动pycharm命令: (1)进入/usr/local/sbin这个目 ...

  2. javascript: 常用操作

    1,取得输入框的输入值,修改输入框的输入值 根据id获取id的值 jquery代码: $('#version_number').val(); 解释:$是jQuery的标准用法,('#version_n ...

  3. Hibernate查询、连接池、二级缓存

    Hibernate第三天: 1. 对象状态 2. session缓存 3. lazy懒加载 4. 映射 一对一对映射 组件/继承映射 目标: 一.hibernate查询 二.hibernate对连接池 ...

  4. nodejs【伪】入门教程

    声明: 本文适合白的不能再白的小白 不要被标题误导,本文不会讲nodejs基础,只是本人学习流程和资料的一个整合 如果想找一大堆教程自己看,没有电梯,自己拉到文章最下方吧   一.nodejs是什么 ...

  5. 简单的setInterval应用

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. php file取重复

    function FetchRepeatMemberInArray($array) { // 获取去掉重复数据的数组 $unique_arr = array_unique ( $array ); // ...

  7. hdu_1254_推箱子(双BFS)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1254 题解:以箱子为主体,第一层BFS,然后用第二层BFS来判断人是否可以到达,这里细节比较多,要注意 ...

  8. how to use tar?

    In UNIX, tar is the most useful tool to compress files (just like zip in Windows.) To compress, inpu ...

  9. find the closest sum to a target value

    problem: given an array of integers including positive and negative, a target value. find 2 numbers ...

  10. ASP.NET获取客户端信息,获取客户端IP等等

    山上明月 ASP.NET能知道的东西 获取服务器电脑名: Page.Server.ManchineName 获取用户信息: Page.User 获取客户端电脑名:Page.Request.UserHo ...