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 ...
随机推荐
- VSCode在Ubuntu下快捷键和Windows下不一致的解决办法
Windows下切换前一次和后一次光标位置,用的快捷键是Alt+<-和Alt+->.很遗憾,Ubuntu下并不是这个快捷键.不清楚为什么VSCode不提供统一的快捷键,但对于我来说,我很想 ...
- centos7 下 yum 安装Nginx
centos7 下 yum 安装和配置 Nginx 添加yum源 Nginx不在默认的yum源中,可以使用epel或者官网的yum源,这里使用官网的yum源 rpm -ivh http://nginx ...
- Keras 训练一个单层全连接网络的线性回归模型
1.准备环境,探索数据 import numpy as np from keras.models import Sequential from keras.layers import Dense im ...
- 显卡,显卡驱动,nvcc, cuda driver,cudatoolkit,cudnn到底是什么?
在使用深度学习框架的过程中一定会经常碰到这些东西,虽然anaconda有时会帮助我们自动地解决这些设置,但是有些特殊的库却还是需要我们手动配置环境,但是我对标题上的这些名词其实并不十分清楚,所以老是被 ...
- Java 获取对象全部属性 包括 父类属性
今天由于业务需要,看一段数据库中的表转化成用户可以看懂的数据,也就是把一些字段比如Date用ms存的,转化为'yyyy-MM-dd'这种格式,但是由于字段太多,所以利用Java反射机制自带的BeanU ...
- org.apache.hadoop.util.Shell demo/例子
package cn.shell; import java.io.IOException; import org.apache.hadoop.util.Shell; public class Shel ...
- MySQL 测试数据批量导入
使用存储过程 方便工作中测试,一次插入多条数据 DELIMITER $$ CREATE PROCEDURE `XXX`.`XXX_test_batch_insert`() BEGIN DECLARE ...
- Bring JavaScript to your Java enterprise with Vert.x
转自:https://opensource.com/article/18/4/benefits-javascript-vertx If you are a Java programmer, chanc ...
- 写一个function,清除字符串前后的空格(兼容所有的浏览器)
function trim1(str){ return str.replace(/(^\s*)|(\s*$)/g,""); }
- 剑指offer 6:链表(从头到尾打印链表)
链表的数据结构 struct ListNode { int value; ListNode* next; }; 那么在链表的末尾添加一个节点的代码如下: void insert(ListNode** ...