arrayList里的快速失败
快速失败是指某个线程在迭代集合类的时候,不允许其他线程修改该集合类的内容,这样迭代器迭代出来的结果就会不准确。
比如用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里的快速失败的更多相关文章
- 集合迭代器快速失败行为及CopyOnWriteArrayList
以下内容基于jdk1.7.0_79源码: 什么是集合迭代器快速失败行为 以ArrayList为例,在多线程并发情况下,如果有一个线程在修改ArrayList集合的结构(插入.移除...),而另一个线程 ...
- Java笔记-快速失败and安全失败
参考资料:http://blog.csdn.net/chenssy/article/details/38151189 快速失败 fail-fast 安全失败 fail-safe java.util包下 ...
- (简单易懂)Java的快速失败(fail-fast)与安全失败,源码分析+详细讲解
之前在程序中遇到快速失败的问题,在网上找解释时发现网上的问题总结都比较片面,故打算自己总结一个,也可以供以后参考. --宇的季节 首先什么是快速失败? 快速失败是为了提示程序员在多线程的情况下不要用线 ...
- 关于java中ArrayList的快速失败机制的漏洞——使用迭代器循环时删除倒数第二个元素不会报错
一.问题描述 话不多说,先上代码: public static void main(String[] args) throws InterruptedException { List<Strin ...
- java ArrayList 迭代器快速失败源码分析
先来看一个例子: @Test void test2() { ArrayList<String> list = new ArrayList<String>(); list.add ...
- 【1】ConcurrentModificationException 异常解析和快速失败,安全失败
目录 一.引起异常的代码 二.foreach原理 三.从ArrayList源码找原因 四.单线程解决方案 五.在多线程环境下的解决方法 一.引起异常的代码 以下三种的遍历集合对象时候,执行集合的rem ...
- 快速失败机制--fail-fast
fail-fast 机制是Java集合(Collection)中的一种错误机制.当多个线程对同一个集合的内容进行操作时,就可能会产生fail-fast(快速失败)事件.例如:当某一个线程A通过iter ...
- 快速失败(fail-fast)和安全失败(fail-safe)的区别
1.fail-fast和fail-safe比较 Iterator的安全失败是基于对底层集合做拷贝,因此,它不受源集合上修改的影响.java.util包下面的所有的集合类都是快速失败的,而java.ut ...
- Java SE之快速失败(Fast-Fail)与快速安全(Fast-Safe)的区别[集合与多线程/增强For](彻底详解)
声明 特点:基于JDK源码进行分析. 研究费时费力,如需转载或摘要,请显著处注明出处,以尊重劳动研究成果:博客园 - https://www.cnblogs.com/johnnyzen/p/10547 ...
随机推荐
- 快速进入pycharm图形界面
解压后的pycharm相关文件的路径:/home/hadoop2/下载/pycharm-community-4.5.4 添加快速启动pycharm命令: (1)进入/usr/local/sbin这个目 ...
- javascript: 常用操作
1,取得输入框的输入值,修改输入框的输入值 根据id获取id的值 jquery代码: $('#version_number').val(); 解释:$是jQuery的标准用法,('#version_n ...
- Hibernate查询、连接池、二级缓存
Hibernate第三天: 1. 对象状态 2. session缓存 3. lazy懒加载 4. 映射 一对一对映射 组件/继承映射 目标: 一.hibernate查询 二.hibernate对连接池 ...
- nodejs【伪】入门教程
声明: 本文适合白的不能再白的小白 不要被标题误导,本文不会讲nodejs基础,只是本人学习流程和资料的一个整合 如果想找一大堆教程自己看,没有电梯,自己拉到文章最下方吧 一.nodejs是什么 ...
- 简单的setInterval应用
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- php file取重复
function FetchRepeatMemberInArray($array) { // 获取去掉重复数据的数组 $unique_arr = array_unique ( $array ); // ...
- hdu_1254_推箱子(双BFS)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1254 题解:以箱子为主体,第一层BFS,然后用第二层BFS来判断人是否可以到达,这里细节比较多,要注意 ...
- how to use tar?
In UNIX, tar is the most useful tool to compress files (just like zip in Windows.) To compress, inpu ...
- find the closest sum to a target value
problem: given an array of integers including positive and negative, a target value. find 2 numbers ...
- ASP.NET获取客户端信息,获取客户端IP等等
山上明月 ASP.NET能知道的东西 获取服务器电脑名: Page.Server.ManchineName 获取用户信息: Page.User 获取客户端电脑名:Page.Request.UserHo ...