• fast-fail和fast-safe机制


    fast-fail(快速失败)

    在使用for循环遍历一个集合时,如果此时改变了集合的结构,如增、删,则会抛出ConcurrentModificationException异常。

    原因:

    • 集合类中有一个modCount变量,在向集合中增加或者删除元素时都会修改这个变量的值;
    • 每当迭代器使用hasNext()/next()遍历下一个元素之前都会检测modCount变量和expectedModCount值是否相等;
    • 如果相等的话就返回遍历,否则抛出异常,终止遍历。

    具体代码如下:

    final void checkForComodification() {  
        if (modCount != expectedModCount) // 1 
            throw new ConcurrentModificationException();  
    } 
    

    需要注意的是,在序号1处,异常的抛出条件时检测到modCount != expectedmodCount 这个条件。如果集合发生变化时修改modCount值, 刚好有设置为了expectedmodCount值, 则异常不会抛出。比如删除了数据,再添加一条数据。所以不能依赖于这个异常是否抛出而进行并发操作的编程, 这个异常只建议检测并发修改的bug。

    使用场景 :

    java.util包下的集合类都是快速失败机制的, 不能在多线程下发生并发修改(迭代过程中被修改).
    fail-safe ( 安全失败 )

    采用安全失败机制的集合容器,在遍历时不是直接在集合内容上访问的,而是先copy原有集合内容,在拷贝的集合上进行遍历。

    原理:

    由于迭代时是对原集合的拷贝的值进行遍历,所以在遍历过程中对原集合所作的修改并不能被迭代器检测到,所以不会出发ConcurrentModificationException。

    缺点:

    基于拷贝内容的优点是避免了ConcurrentModificationException,但同样地, 迭代器并不能访问到修改后的内容。 (简单来说就是, 迭代器遍历的是开始遍历那一刻拿到的集合拷贝,在遍历期间原集合发生的修改迭代器是不知道的)

    使用场景:

    java.util.concurrent包下的容器都是安全失败的,可以在多线程下并发使用,并发修改。

  • 相关阅读:
    socket学习笔记——获取域名与IP(linux)
    socket学习笔记——实现收发文件(Windows)
    socket学习笔记——IO口的基本操作(读、写)
    Microsoft Visual C++ 2010(86) Redistributable不能安装完美解决
    AD转换精度的计算
    cuda编程基础
    CUDA中并行规约(Parallel Reduction)的优化
    Warp divergence
    提取图片中文字
    GPU基本概念详解
  • 原文地址:https://www.cnblogs.com/reecelin/p/13380695.html
Copyright © 2020-2023  润新知