博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Fail-Fast机制详解
阅读量:6160 次
发布时间:2019-06-21

本文共 1848 字,大约阅读时间需要 6 分钟。

  Java中的Iterator非常方便地为所有的数据源提供了一个统一的数据读取(删除)的接口,但是在使用的时候容易报如下错误ConcurrentModificationException,原因是在使用迭代器时候底层数据被修改,最常见于数据源不是线程安全的类,如HashMap & ArrayList等。如下代码所示:

public class FailFastDemo {    public static void main(String[] args)throws Exception {        List objects = new ArrayList();        objects.add("object1");        objects.add("object2");        objects.add("object3");        Iterator iterator = objects.iterator();        while (iterator.hasNext()) {            Object object = iterator.next();            System.out.println(object);            objects.remove(object);        }    }}
View Code

产生原因

  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保存的值是否相等。如果相等,说明在遍历的过程中集合类内有发生改变;如果不相等说明在遍历的过程中,集合中的数据发生了改变此时就抛出ConcurrentModificationExceptionfast-fail是JDK为了提示开发者将非线程安全的类使用到并发的场景下时,抛出一个异常,及早发现代码中的问题。
补充:
  fast-fail的Iterator本身也提供了remove()来删除当前遍历到的元素,例如:ArrayListIterator中的remove(),可以在迭代过程中删除当前数据而不抛出ConcurrentModificationException

public class FailFastDemo {    public static void main(String[] args)throws Exception {        List objects = new ArrayList();        objects.add("object1");        objects.add("object2");        objects.add("object3");        Iterator iterator = objects.iterator();        while (iterator.hasNext()) {            Object object = iterator.next();            System.out.println(object);            iterator.remove();        }    }}
View Code

 

转载地址:http://lrafa.baihongyu.com/

你可能感兴趣的文章
润乾报表 - 细节问题
查看>>
用python快速开发一个实用的socket服务器
查看>>
js操作HTML的select
查看>>
mvc教程
查看>>
pku 3207 Ikki's Story IV - Panda's Trick 2-sat判定是否存在可行解
查看>>
Ubuntu12.04上编译PlateGatewayQt
查看>>
connect()在UDP连接中的应用一例
查看>>
VC:多线程编程
查看>>
ASP.NET MVC资源文件多语言实现方式
查看>>
.NET Framework
查看>>
play framework anorm orm 化构想
查看>>
【声波传钱】支付宝新功能 “声波支付” 自动售货机已投入试运
查看>>
windows设备坐标和逻辑坐标的转换
查看>>
Linux手动导入导出mysql数据库
查看>>
跨线程更新控件UI
查看>>
Main函数参数argc,argv说明
查看>>
Debian 7 Wheezy 安装 VirtualBox
查看>>
SSMS 2005 连接 SQL SERVER 2008问题
查看>>
Android用户界面开发:控件集合
查看>>
RFID Cooking with Mifare Classic
查看>>