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 ...
随机推荐
- leecode第一百六十题(相交链表)
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode ...
- Fabric 1.0交易流程
这篇文章详细介绍fabric的交易流程,以图片加文字的形式呈现. Fabric 1.0交易流程 fabric中的所有交易都是通过chaincode执行 1.应用程序客户端通过SDK调用证书服务(CA) ...
- mysql查询出相同数据出现的次数,统计相同值的数量
1.可以使用count SELECT count(name='A' OR NULL) FROM table 2.用sum SELECT sum(if( = 'A', 1, 0)) FROM table ...
- liunx文件操作 文件压缩
文件备份和压缩命令 在Linux中,常用的文件压缩工具有gzip,bzip2,zip. 'bzip2'是最理想的压缩工具,它提供了最大限度的压缩. 'zip'兼容好,windows也支持. bzip2 ...
- css清除常用默认样式表
/*公共样式*/ html, body, div, ul, li, h1, h2, h3, h4, h5, h6, p, dl, dt, dd, ol, form, input, textarea, ...
- python四
三元运算 name = "张三" if 1 == 2 else "李四" print(name) name1 = "张三" if 1 == ...
- 聊一聊啥都不会的我自学Linux系统的历程
Linux大家都不陌生,我是在大三的时候开始接触Linux,上课的时候一位给我们上课的老师闲聊的时候说,你们计算机专业的学生要好好去学Linux,对于你们以后发展或者是就业都很有帮助. 开始的时候是一 ...
- SHOW Syntax
MySQL 5.5 Reference Manual / SQL Statement Syntax / Database Administration Statements / SHOW ...
- PHP 第三方支付
以前事情比较繁忙,压根都没有时间去整理最近的工作. 最近稍微轻松点,就把自己在公司处理的支付业务拿出来,留个纪念,顺道回顾下以前自己支付的知识. 俗话说实践是检验整理的唯一标准,东西做的是否能用,只能 ...
- C#设置随机整数
JQuery var x = 5;//最大值var y = 1;//最小值var rand = parseInt(Math.random() * (x - y + 1) + y); Mvc控制器 Ra ...