Fail-Fast机制详解
Java中的Iterator非常方便地为所有的数据源提供了一个统一的数据读取(删除)的接口,但是在使用的时候容易报如下错误ConcurrentModificationException,原因是在使用迭代器时候底层数据被修改,最常见于数据源不是线程安全的类,如HashMap & ArrayList等。如下代码所示:
public class FailFastDemo {
public static void main(String[] args)throws Exception {
List<Object> objects = new ArrayList<Object>();
objects.add("object1");
objects.add("object2");
objects.add("object3");
Iterator<Object> iterator = objects.iterator();
while (iterator.hasNext()) {
Object object = iterator.next();
System.out.println(object);
objects.remove(object);
}
}
}
产生原因
Java中的集合类分为两种类型:线程安全,位于java.util.concurrent命名目录下,如CopyOnWriteArrayList;线程不安全:位于java.util目录下,如ArrayList,HashMap。所谓线程安全是在多线程环境下,这个类还能表现出和行为规范一致的结果。既然有线程安全的集合,为什么还要使用线程非安全的集合呢呢?因为线程安全的类通常需要通过各种手段去保持对数据访问的同步,会降低数据访问的效率。使用非线程安全的集合类在非并发场景具有很大的优势。如果开发者在使用时没有注意,将非线程安全的集合类用在了并发的场景下,比如线程A获取了ArrayList的iterator,然后线程B通过调用ArrayList.add()修改了ArrayList的数据,此时就有可能会抛出ConcurrentModificationException。
原理很简单,构建Iterator时将当前ArrayList的modCount保存在
expectedModCount之中
,当下一次调用next()时,会判断ArrayList的modCount值和iterator内部expectedModCount
保存的值是否相等。如果相等,说明在遍历的过程中集合类内有发生改变;如果不相等说明在遍历的过程中,集合中的数据发生了改变此时就抛出ConcurrentModificationException。fast-fail是JDK为了提示开发者将非线程安全的类使用到并发的场景下时,抛出一个异常,及早发现代码中的问题。
补充:
fast-fail的Iterator本身也提供了remove()来删除当前遍历到的元素,例如:ArrayListIterator中的remove(),可以在迭代过程中删除当前数据而不抛出ConcurrentModificationException:
public class FailFastDemo {
public static void main(String[] args)throws Exception {
List<Object> objects = new ArrayList<Object>();
objects.add("object1");
objects.add("object2");
objects.add("object3");
Iterator<Object> iterator = objects.iterator();
while (iterator.hasNext()) {
Object object = iterator.next();
System.out.println(object);
iterator.remove();
}
}
}
Fail-Fast机制详解的更多相关文章
- 转 Java虚拟机5:Java垃圾回收(GC)机制详解
转 Java虚拟机5:Java垃圾回收(GC)机制详解 Java虚拟机5:Java垃圾回收(GC)机制详解 哪些内存需要回收? 哪些内存需要回收是垃圾回收机制第一个要考虑的问题,所谓“要回收的垃圾”无 ...
- Java SPI机制详解
Java SPI机制详解 1.什么是SPI? SPI 全称为 (Service Provider Interface) ,是JDK内置的一种服务提供发现机制.SPI是一种动态替换发现的机制, 比如有个 ...
- 从mixin到new和prototype:Javascript原型机制详解
从mixin到new和prototype:Javascript原型机制详解 这是一篇markdown格式的文章,更好的阅读体验请访问我的github,移动端请访问我的博客 继承是为了实现方法的复用 ...
- 浏览器 HTTP 协议缓存机制详解
最近在准备优化日志请求时遇到了一些令人疑惑的问题,比如为什么响应头里出现了两个 cache control.为什么明明设置了 no cache 却还是发请求,为什么多次访问时有时请求里带了 etag, ...
- JVM的垃圾回收机制详解和调优
JVM的垃圾回收机制详解和调优 gc即垃圾收集机制是指jvm用于释放那些不再使用的对象所占用的内存.java语言并不要求jvm有gc,也没有规定gc如何工作.不过常用的jvm都有gc,而且大多数gc都 ...
- ThreadPoolExecutor运转机制详解
ThreadPoolExecutor运转机制详解 - 走向架构师之路 - 博客频道 - CSDN.NET 最近发现几起对ThreadPoolExecutor的误用,其中包括自己,发现都是因为没有仔细看 ...
- Linux 内存机制详解宝典
Linux 内存机制详解宝典 在linux的内存分配机制中,优先使用物理内存,当物理内存还有空闲时(还够用),不会释放其占用内存,就算占用内存的程序已经被关闭了,该程序所占用的内存用来做缓存使用,对于 ...
- PHP的垃圾回收机制详解
原文:PHP的垃圾回收机制详解 最近由于使用php编写了一个脚本,模拟实现了一个守护进程,因此需要深入理解php中的垃圾回收机制.本文参考了PHP手册. 在理解PHP垃圾回收机制(GC)之前,先了解一 ...
- Java 反射 设计模式 动态代理机制详解 [ 转载 ]
Java 反射 设计模式 动态代理机制详解 [ 转载 ] @author 亦山 原文链接:http://blog.csdn.net/luanlouis/article/details/24589193 ...
- Android事件分发机制详解
事件分发机制详解 一.基础知识介绍 1.经常用的事件有:MotionEvent.ACTION_DOWN,MotionEvent.ACTION_MOVE,MotionEvent.ACTION_UP等 2 ...
随机推荐
- vue2.0自定义指令的使用方法
感觉2.0好坑啊,自定义指令和1.0完全不一样,并且文档写得也不太清晰,下面是我写得一个demo,希望帮助大家更好地理解自定义指令 <!DOCTYPE html> <html lan ...
- python学习随笔(一)
我是为记录学习python的过程而开通了博客,希望以后自己能看看,也希望能分享一些给初学者. 话不多说,开始第一篇. (一)python解释器. python2和3,现在python2是主流,但是py ...
- Struts2的类型转换(上)
传统的类型转换.(略) Struts2中提供了内置的基本的类型转换器,可以实现基本类型的自动转换,包括: Integer, Float, Double, Decimal Date and Dateti ...
- 【Egret】使用Egret开发的HTML5项目,使用本地电脑作为服务器进行移动端调试流程
流程: 1.先开启本机IIS服务器 具体开启流程如下:http://www.jb51.net/article/29787.htm 2.添加服务器MIME类型, 按照以下两个教程把所有的MIME类型都添 ...
- 庆祝POPTEST签约企业培训
庆祝POPTEST签约企业培训 POPTEST与众多培训企业进行技术PK,由于企业认可POPTEST的技术实力,从众多竞争对手中脱颖而出,成功中标清华控股子公司性能测试培训.
- 老李分享:HTTP协议之协议头
老李分享:HTTP协议之协议头 当我们打开一个网页时,浏览器要向网站服务器发送一个HTTP请求头,然后网站服务器根据HTTP请求头的内容生成当次请求的内容发送给浏览器.你明白HTTP请求头的具体含 ...
- Android中的java层的线程暂停和恢复实现
/** * 基础线程对象. * * @author jevan * @version (1.0 at 2013-6-17) * @version (1.1 at 2013-7-2) 增加on ...
- JavaScript高级程序设计---学习笔记(四)
1.全局变量不能通过delete操作符删除,而直接在window对象上定义的属性可以. var age = 29; window.color = "red"; delete age ...
- C#变量、常量、枚举、预处理器指令知多少
一.变量 C#共有其中变量类型有:静态变量.实类变量.数组元素.数值参数.引用参数.输出参数和局部变量 先定义一个简单的类来说明,如下: public class VariableDefine { p ...
- 初学 Java Script (算数运算及逻辑术语)
在JS中常用的算数运算符与其他编程类语言类似,逻辑术语也近乎相同. 一.常用算数运算符 1.基本算数运算符 赋值运算符:= : 加号:+ : 减号: - : 乘号: * : 除号: / : 求余: % ...