java fail-fast和fail-safe
快速失败(fail—fast)
在用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的内容进行了修改(如增加、删除等),则会抛出Concurrent Modification Exception。
public static void main(String[] args) {// 集合list中存有4个变量
List<Integer> list = new ArrayList<>();
list.add(0);
list.add(1);
list.add(2);
list.add(3);
try {
Iterator<Integer> itr = list.iterator();
// 迭代遍历时,向list中添加元素
for (int i=0; i<4; i++) {
System.out.println(itr.next());
list.add(i+4, i+4);
}
}
catch (Exception e) {
System.out.println(e);
}
}
输出结果为:
0
java.util.ConcurrentModificationException
原理:集合中定义变量modCount来记录集合的变化,如每次添加或删除元素,modCount加1 。迭代器在遍历时直接访问集合中的内容,并且在遍历过程中使用一个 expectedmodCount变量,初始值为modCount。集合在被遍历期间如果内容发生变化,就会改变modCount的值。每当迭代器使用next()遍历下一个元素之前,都会检测modCount变量是否为expectedmodCount值,是的话就返回遍历;否则抛出异常,终止遍历。
注意:这里异常的抛出条件是检测到 modCount!=expectedmodCount 这个条件。如果集合发生变化时修改modCount值刚好又设置为了expectedmodCount值,则异常不会抛出。因此,不能依赖于这个异常是否抛出而进行并发操作的编程,这个异常只建议用于检测并发修改的bug。
修改集合中已存在的元素并不会触发异常,如在遍历list时,执行list.set(0, 3);
场景:java.util包下的集合类都是快速失败的,不能在多线程下发生并发修改(迭代过程中被修改)。
安全失败(fail—safe)
采用安全失败机制的集合容器,在遍历时不是直接在集合内容上访问的,而是先复制原有集合内容,在拷贝的集合上进行遍历。
public static void main(String[] args) {
// 集合list中存有4个变量
List<Integer> list = new CopyOnWriteArrayList<>();
list.add(0);
list.add(1);
list.add(2);
list.add(3);
try {
Iterator<Integer> itr = list.iterator();
// 迭代遍历时,向list中添加元素
for (int i=0; i<4; i++) {
System.out.println(itr.next());
list.add(i+4, i+4);
}
}
catch (Exception e) {
System.out.println(e);
}
}
输出结果:0 1 2 3
迭代遍历时,向list中添加元素,并不会抛出异常。且遍历的结果为list初始的所有元素。
原理:由于迭代时是对原集合的拷贝进行遍历,所以在遍历过程中对原集合所作的修改并不能被迭代器检测到,所以不会触发Concurrent Modification Exception。
缺点:基于拷贝内容的优点是避免了Concurrent Modification Exception,但同样地,迭代器并不能访问到修改后的内容,即:迭代器遍历的是开始遍历那一刻拿到的集合拷贝,在遍历期间原集合发生的修改迭代器是不知道的。
场景:java.util.concurrent包下的容器都是安全失败,可以在多线程下并发使用,并发修改。
fail-fast和 fail-safe 的区别
| Fail Fast Iterator | Fail Safe Iterator | |
|---|---|---|
| Throw ConcurrentModification Exception | Yes | No |
| Clone object | No | Yes |
| Memory Overhead(内存开销) | No | Yes |
| Examples | HashMap,Vector,ArrayList,HashSet | CopyOnWriteArrayList, ConcurrentHashMap |
java fail-fast和fail-safe的更多相关文章
- Fail Fast and Fail Safe Iterators in Java
https://www.geeksforgeeks.org/fail-fast-fail-safe-iterators-java/ Fail Fast and Fail Safe Iterators ...
- fail fast和fail safe策略
优先考虑出现异常的场景,当程序出现异常的时候,直接抛出异常,随后程序终止 import java.util.ArrayList; import java.util.Collections; impor ...
- 快速失败(fail—fast)和 安全失败(fail—safe)
快速失败(fail-fast) 在用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的结构进行了修改(增加.删除),则会抛出Concurrent Modification Exception. 原理 ...
- 【问题】Could not locate PropertySource and the fail fast property is set, failing
这是我遇到的问题 Could not locate PropertySource and the fail fast property is set, failing springcloud的其他服务 ...
- FastDFS :java.lang.Exception: getStoreStorage fail, errno code: 28
FastDFS 服务正常,突然报错:java.lang.Exception: getStoreStorage fail, errno code: 28 答:错误代码28表示 No space left ...
- Java集合框架中的快速失败(fail—fast)机制
fail-fast机制,即快速失败机制,是java集合框架中的一种错误检测机制.多线程下用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的内容进行了修改(增加.删除),则会抛出Concurre ...
- android studio java.io.IOException:setDataSourse fail.
这一次是针对Android开发中的一个小问题,权限获取的问题. 在写了一个一个小Android程序的时候,有时候普需要获取本机的文件(Audio&Video),这时候如果不加权限就会出现这种情 ...
- java中fail-fast 和 fail-safe的区别
java中fail-fast 和 fail-safe的区别 原文地址:http://javahungry.blogspot.com/2014/04/fail-fast-iterator-vs-fa ...
- 面试题思考:java中快速失败(fail-fast)和安全失败(fail-safe)的区别是什么?
一:快速失败(fail—fast) 在用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的内容进行了修改(增加.删除.修改),则会抛出Concurrent Modification Exceptio ...
随机推荐
- Java 设置PDF文档背景——单色背景、图片背景
一般生成的PDF文档默认的文档底色为白色,我们可以通过一定方法来更改文档的背景色,以达到文档美化的作用. 以下内容提供了Java编程来设置PDF背景色的方法.包括2种设置方法: 设置纯色背景色 设置图 ...
- vue中插入Echarts示例(菜鸟记录)
- JQUERY的属性进行操作
Jquery方式操作属性(attribute) $().attr(属性名称); //获得属性信息值 $().attr(属性名称,值); //设置属性的信息 $().removeAttr(属性 ...
- Geoserver+Postgresql+PostGIS 进行数据发布
1.postgressql+postgis安装 由于我已经安装了,因此没法进行截图,给出下载地址 下载地址:https://www.postgresql.org/ 记得一定要下载edu的版本 因为这个 ...
- hbase大规模数据写入的优化历程 ,ZZ
http://blog.csdn.net/zbc1090549839/article/details/51582817
- Golang 容器和不同header的解析
记录一下,用golang实现一个静态资源容器,膜拜下强人 http.Handle("/", http.FileServer(http.Dir(currentPath+"/ ...
- oracle中日期类型 to_date 和to_timestamp什么区别啊?
1.to_date() 和to_timestamp()区别 由于oracle中date类型只支持到秒,不支持到毫秒,所以to_date()不能取到毫秒.如果要取到毫秒,oracle 9i以上版本,可以 ...
- python安装requests
下面是requests的安装步骤: 1.如果系统已经装了Python,把D:\python3.6.5\Scripts添加到系统的环境变量PATH后面 2.cmd下cd到这个目录下D:\Python3. ...
- redis特性,使用场景
redis特性: 1.redis保存在内存中,读写速度快. 2.redis--持久化(断电数据不丢失:对数据的更新将异步保存到磁盘上). 3.redis数据结构丰富 4.redis功能丰富 5.简单( ...
- Saiku相关异常处理(十五)
Saiku大概是我的第一个持续更博的技术点,希望自己能在这条研究saiku的道路上越走越远嘻嘻 这里我们来记录一下研究saiku时遇到的异常信息,这篇博客会保持持续更新的. 1. Java heap ...