fail fast和fail safe策略
优先考虑出现异常的场景,当程序出现异常的时候,直接抛出异常,随后程序终止
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List; class Main{
public static void main(String[] args) {
List<String> list = new ArrayList<>();
Collections.addAll(list,"A","B","C","D");
//modCount = 4,从0开始
Iterator<String> iterator = list.iterator();//取得集合迭代器(取得当前集合的副本),expectedModCount = 4
//当取得集合迭代器的时候(及调用list.iterator()),expectedModCount=modCount
while(iterator.hasNext()){
String str = iterator.next();//每次调用这句代码时候 会调用checkForComodification()
//以此来检查副本中的expectedModCount是否等于集合中的modCount,为了安全考虑(保证不会脏读)
if(str.equals("B")){
//list.remove("B"); //modCount +1=5 ConcurrentModificationException
iterator.remove();
continue;
}
}
}
}
fail-fast机制
ConcurrentModificationException,Collection集合使用迭代器遍历的时候,使用了集合类提供的修改集合内容方法报错
产生原因:
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
collection集合中的modCount表示当前集合修改的次数(remove,add调用的时候,modCount++)
在并发使用的场景中如果发生值的修改保证用户独到的是当前集合的最新值,而不会发生脏读
当取得集合迭代器的时候(及调用list.iterator()),expectedModCount=modCount
换言之,迭代器就是当前集合的一个副本
而如果是有了Iterator迭代器提供的remove()不会出现此错误,本质上在remove时候将modCount重新赋值给expectedModCount
fail safe集合
不抛出此异常的集合
fail-safe:不产生ConcurrentModificationException异常
juc包下线程安全的集合类(CopyOnWriteArrayList、ConcurrentHashMap)
总结:以后在迭代器遍历的时候,不要修改集合的内容
1.为何产生fail fast?
ModCount expectedModCount存在于内部迭代器实现,存储当前集合修改次数
modCount存在于AbstractList记录List集合被修改(add remove)的次数
2.fail fast的意义:保证多线程场景下读取数据不会发生脏读,当有一个线程修改集合的时候,告诉客户端拿到的数据并非最新的
当执行list.remove()的时候,判断元素的下标,使用fastRemove,此时modCount++,不再等于expectedModCount
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)
快速失败(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的其他服务 ...
- Java集合框架中的快速失败(fail—fast)机制
fail-fast机制,即快速失败机制,是java集合框架中的一种错误检测机制.多线程下用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的内容进行了修改(增加.删除),则会抛出Concurre ...
- 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 Exception. ...
- Netty学习路线总结
序 之前开过品味性能系列.Mysql学习系列,颇为曲高和寡.都是讲理论,很少有手把手深入浅出的文章.不过确实我就这脾气,文雅点的说法叫做"伪雅",下里巴人叫做"装逼&qu ...
- 面试题思考:java中快速失败(fail-fast)和安全失败(fail-safe)的区别是什么?
一:快速失败(fail—fast) 在用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的内容进行了修改(增加.删除.修改),则会抛出Concurrent Modification Exceptio ...
- java中快速失败(fail-fast)和安全失败(fail-safe)的区别是什么?
一:快速失败(fail—fast) 在用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的内容进行了修改(增加.删除.修改),则会抛出Concurrent Modification Exceptio ...
随机推荐
- Elasticsearch高版本安装head插件
安装Elasticsearch 1.安装Elasticsearch-6.5.4.tar.gz [merce@info5 ~]$ cd /appmerce/zrapp/ [merce@info5 zra ...
- mac下sourcetree创建git分支和合并分支
git默认创建的分支为:master主分支 要实现的效果:新建和合并分支. 1.在master基础上创建分支v1.0.1并切换至v1.0.1然后推送分支到远程服务器 确定即可!! 然后查看远端已经发现 ...
- GOJS的使用
项目当中要求表与表之间建立关联关系,需要用到Gojs(只想说这是个什么?),以前完全没接触过gojs,所以记录下使用中的技巧和方法 http://www.devtalking.com/articles ...
- django 基础进 COOKIE
1 cookie session auth cookie概念:针对每一个服务器,保存在客户端浏览器的一个key-value结构数据,可以理解成一个字典结构 cookie语法: ...
- mapreduce 读写Parquet格式数据 Demo
import java.io.IOException; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs ...
- [Algorithm] 202. Happy Number
Write an algorithm to determine if a number is "happy". A happy number is a number defined ...
- query 2019徐州网络赛(树状数组)
query \[ Time Limit: 2000 ms \quad Memory Limit: 262144 kB \] 题意 补题才发现比赛的时候读了一个假题意.... 给出长度为 \(n\) 的 ...
- Huffman树与Huffman编码
1.Huffman树 今天复习Huffman树.依稀记得自己被Huffman树虐的经历.还记得是7月份,我刚开始看数据结构与算法,根本看不懂Huffman树的操作.后来我终于悟出了Huffman树是怎 ...
- ELK原理
为什么要使用Elasticsearch? 因为在我们中的数据,会随着时间变的非常多,若采用以往的模糊查询,模糊查询前置通配符,如:"%aa%",会放弃索引,导致数据表查询将变成全 ...
- Git-push和pull分支
查看分支信息:git branch -r 查看所有分支信息:git branch -a 本地推送分支:git push origin branch-name 推送分支前最好先pull分支:git pu ...