【转载】ArrayList 中数据删除 fail fast
2019独角兽企业重金招聘Python工程师标准>>>
本文转载自http://shift-alt-ctrl.iteye.com/blog/1839147
在循环arrayLlist时,经常会遇到remove操作,那么arrayList的remove的底层是怎么做的?
AbstractList中,有一个属性modCount,这个属性是跟踪list中数据被修改的次数,任何对list的add/remove操作,都将导致modCount++.
在AbstractList中还有一个内部类Itr implements Iterator,Itr是一个list遍历的工具类,当然list.iterator()方法也是返回Itr对象,在Itr中有一个校验位属性expectedModCount;对于一个itr对象,其初始时expectedModCount=modCount.
Iterator是list一个视图,其最终还是操作list的存储结构.在使用iterator遍历时,remove()操作,会导致modCount++(AbstractList.remove()),但是还有expectedModCount=modCount,即在iterator中remove数据,会带来expectedModCount与modCount值的同步.
在Iterator遍历时,next(),remove()方法会校验expectedModCount与modCount值是否一致,如果不一致,就意味着这list数据在iterator外部被修改,此时iterator遍历将会造成ConcurrentModificationException.
AbstractLlist不仅支持普通的iterator,还支持ListIterator(ArrayList,LinkedList均支持),ListIterator增加了遍历时双向游标能力(previous,next),增加了add方法.add方法和remove方法一样也做了expectedModCount和modCount一致性校验.
引申一下,如下四个对list数据删除的代码,有区别吗??
如下是4中循环方式:
1) for(int i=0;i<list.size();i++){
list.remove(i);
}
2) for(int i=list.size()-1;i>=0;i--){
list.remove(i);
}
3)
int size = list.size();
for(int i=size-1;i>-1;i--){
list.remove(i);
}
4) for(Object i : list){
list.remove(i);//如果list中存在多个Object互相equals时,此方法仍然有效.注意list.remove(Object)内部使用了遍历操作,并使用equals来比较对象并删除.
}
5) Iterator it = list.iterator()
while(it.hasNext()){
it.next();
it.remove();
}
1),2),3)是最普通的遍历方式,但是在遍历并有删除操作时,似乎它们执行的结果还有些差距,根据坐标删除,那么1)实事上只会有一半被删掉,1)中每删除一次,计算一次list.size(),但是当前i++,且前端删除会造成数组结构copy.
2)后端删除,不会造成copy,每次都是删除最后一个位置,直至结束
3)因为size没有重新计算,在删除一半数据后,抛出IndexOutOfBoundsException
4)/5)正常
提示:foreach方式最终是转换成了iterator的方式进行.(产生于编译过程中).
关于fail fast:
在并发的时候,如果线程A正遍历一个collection(List, Map, Set etc.),这时另外一个线程B却修改了该collection的size,线程A就会抛出一个错:ConcurrentModificationException,表明:我正读取的内容被修改掉了,你是否需要重新遍历?或是做其它处理?这就是fail-fast的含义。
Fail-fast是并发中乐观(optimistic)策略的具体应用,它允许线程自由竞争,但在出现冲突的情况下假设你能应对,即你能判断出问题何在,并且给出解决办法。悲观(pessimistic)策略就正好相反,它总是预先设置足够的限制,通常是采用锁(lock),来保证程序进行过程中的无错,付出的代价是其它线程的等待开销:
Doug Lea的concurrent包给出了另外一种解决方案,Copy On Write。它的CopyOnWriteArrayList、CopyOnWriteArraySet会在线程B试图修改数据容器时,给出一个copy出来的容器(当然,我们程序中是感觉不到的),这样线程A在老版本的v上遍历,线程B则在新版本的v上修改,两者互不相干,也决不会出现ConcurrentModificationException。它的代价则主要是在容器的copy上,当并发程度越高,其开销也越高。
所以,Fast Fail被引入JDK的一个基本前提是:你绝大多数的情形,仅仅是在遍历一个collection,不会有另外的线程会对它做update。如此,它的效率是最充分的。但如果你不断遇到ConcurrentModificationException的异常时,则要考虑是否要进行一定次数的重新遍历,或者干脆采用悲观策略锁住资源来保证线程安全。
转载于:https://my.oschina.net/javahongxi/blog/1523865
【转载】ArrayList 中数据删除 fail fast相关推荐
- oracle12c 清理归档,Oracle 12c中数据删除(delete)新特性之数据库内归档功能
有些应用有"标记删除"的概念,即不是删除数据,而是数据依然保留在表中,只是对应用不可见而已.这种需求通常通过如下方法实现: 1) 给相关表增加一个另外的列,该列存储标志数据被删除 ...
- mysql删除表中数据
方法1:delete from 表名; 方法2:truncate table 表名; 比 较: 1> truncate 是整体删除 (速度较快),delete是逐条删除 (速度较慢) 2> ...
- MySQL中的删除:drop,delete,truncate的区别和联系
MySQL中drop,delete,truncate都可以用于删除,那么它们之间的区别是什么呢?首先我们先来学习一下这三个命令.注:本篇文章主要介绍对于表的删除 一.drop命令 drop是DDL(数 ...
- Java - Java集合中的快速失败Fail Fast 机制
文章目录 什么是 fail-fast 源码解读 Itr 为什么对集合的结构进行修改会发生并发修改异常-源码分析 修改方法之 remove 修改方法之 add 案例分享 [案例一] [案例二] [案例三 ...
- java list 合并 重复的数据_Java ArrayList合并并删除重复数据3种方法
首页 > 基础教程 > 集合框架 > ArrayList类 Java ArrayList合并并删除重复数据3种方法 1. 通过List自带方法list.retainAll() Lis ...
- Mysql清空表(truncate)与删除表中数据(delete)的区别
2019独角兽企业重金招聘Python工程师标准>>> 为某基于wordpress搭建的博客长久未除草,某天升级的时候发现已经被插入了几万条垃圾留言,如果一条条删除那可真是累人的活. ...
- Java 删除ArrayList中重复元素,保持顺序
// 删除ArrayList中重复元素,保持顺序 public static List<Map<String, Object>> removeDuplica ...
- Java删除ArrayList中的重复元素的2种方法
ArrayList是Java中最常用的集合类型之一.它允许灵活添加多个null元素,重复的元素,并保持元素的插入顺序.在编码时我们经常会遇到那种必须从已建成的ArrayList中删除重复元素的要求.这 ...
- Java 中ArrayList中的重复数据
以下介绍五种-不同的方法去除 Java 中ArrayList中的重复数据 1.使用LinkedHashSet删除arraylist中的重复数据 LinkedHashSet是在一个ArrayList删除 ...
最新文章
- 一个数学系毕业的物理学家,是怎么拿到诺贝尔化学奖的?
- title和alt属性
- Springmvc+Easyui 搜索,新增,删除,修改
- 【运筹学】线性规划 单纯形法 ( 基矩阵 | 基变量 | 非基矩阵 | 非基变量 | 矩阵分块形式 | 逆矩阵 | 基解 | 基可行解 )
- C语言指针(个人的认识)
- 百度爬虫爬到虚拟链接 网站被黑_网站地图sitemap对SEO优化有什么作用?
- Java:假设车库有3个车位(可以通过boolean[]数组来表示车库)可以停车,写一个程序模拟多个用户开车离开,停车入库的效果。注意:车位有车时不能停车。
- msdn画圆弧函数_画直线不简单!python-matplotlib告诉你为什么
- 互联网晚报 | 12月14日 星期二 | “植发第一股”雍禾医疗登陆港交所;商汤科技将延迟上市;“拍照搜题”等作业APP暂时下线...
- unity案例 mysql lua_通过Xlua实现unity热更新的一个小例子
- Entity Framework 4.1 (强转)
- teamview外网连接服务器虚拟主机,利用路由器端口映射+桥接虚拟机搭建个人服务器...
- php 识别图框,自动识别比例插入CAD图框教程
- 等级保护2.0的变化
- 为什么会有带www的域名和不带www的域名
- 即时通信工具中同步离线会话消息的方法及装置
- 干货分享|如何使用小鸟云服务器搭建Wordpress站点
- echarts图表动态化
- 原生js制作动画效果
- 混音软件哪个好用?这几个软件不容错过