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 ...
随机推荐
- 在腾讯云上部署Hexo博客
推荐理由 ----搭建个人的空间博客目前深受个人开发者的追捧,然而博客的种类和平台有很多,Hexo是一个开源的静态博客生成器.相比于其他博客而言它只要是web容器就能用.除了闷头专研技术之外,程序员还 ...
- ECMAScript6-解构
▓▓▓▓▓▓ 大致介绍 解构:就是将声明的一组变量和与相同结构的数组或者对象的元素数值一一对应,并将变量相对应元素进行赋值 ▓▓▓▓▓▓ 数组解构 例子: let [a,b,c] = [1,2,3]; ...
- 【干货分享】sketch 前端开发常用技巧总结
sketch横空出世,移动端的应用越来越多的采用sketch来做,前端开发也需要掌握更多sketch技巧. (1) sketch导出图片时,如何快速选择多个图层? 1. 在画布上任一点单击并拖拽出一个 ...
- placeholder的字体样式改变,滚动条的颜色改变,ios日期兼容
placeholder:::-webkit-input-placeholder { color: rgba(153, 153, 153, 0.541);font-size:12px;}:-moz-pl ...
- 数据库dbutils
common-dbutils.jarQueryRunnerupdate方法:* int update(String sql, Object... params) --> 可执行增.删.改语句* ...
- 为什么使用 Containjs 模块化管理工具效率高?
为什么使用 Containjs 模块化管理工具效率高? 要说明这个首先得说明一下,Containjs 的模块加载原理. 第一步,首先使用异步加载(ajax)在 js 目录下的 app.js 入口模块( ...
- JQ实战一之烟花
本次的效果大概为当用户点击网页时,网页下方弹出一个类似烟花的长条条,然后在桌面上散开以达成类似烟花的特效.话不多说先上图. 首先布局,布局很简单 <style> body { backgr ...
- 手机自动化测试:appium源码分析之bootstrap五
手机自动化测试:appium源码分析之bootstrap五 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.poptest测试 ...
- 第一个SignalR案例
说明:开发的案例为Hub(集线器) 一.开发环境 VS2013 ,window10 二.步骤 打开vs创建一个新的解决方案,添加一个空的WebForm项目. 使用NuGet添加引用.命令:PM> ...
- 基础:获得servletAPI
package com.learning.web.action; import javax.servlet.ServletContext; import javax.servlet.http.Http ...