• 快速失败(fail-fast)和安全失败(fail-safe)的区别


    java.util包下面的所有的集合类都是快速失败的,而java.util.concurrent包下面的所有的类都是安全失败的。快速失败的迭代器会抛出ConcurrentModificationException异常,而安全失败的迭代器永远不会抛出这样的异常。

    快速失败示例

    public class FailFastTest {
        
        //(01) 新建了一个ArrayList,名称为arrayList。
        private static List<Integer> list = new ArrayList<>();   
        
        public static void main(String[] args) {
            //(02) 向arrayList中添加内容
            for(int i = 0 ; i < 10;i++){
                list.add(i);
            }
            //(03) 新建一个“线程a”,并在“线程a”中通过Iterator反复的读取arrayList的值。
            new threadOne().start();
            //(04) 新建一个“线程b”,在“线程b”中删除arrayList中的一个“节点A”。
            new threadTwo().start();
        }
        
        /**
         * @desc:线程one迭代list
         */
        private static class threadOne extends Thread{
            public void run() {
                Iterator<Integer> iterator = list.iterator();
                while(iterator.hasNext()){
                    int i = iterator.next();
                    System.out.println("ThreadOne 遍历:" + i);
                }
            }
        }
        
        /**
         * @desc:线程two修改list
         */
        private static class threadTwo extends Thread{
            public void run(){
                int i = 0 ; 
                while(i < 6){
                    System.out.println("ThreadTwo run:" + i);
                    if(i == 2){
                        list.remove(i);
                    }
                    i++;
                }
            }
        }
    }

    fail-fast机制,是一种错误检测机制。它只能被用来检测错误,因为JDK并不保证fail-fast机制一定会发生。若在多线程环境下使用fail-fast机制的集合,建议使用“java.util.concurrent包下的类”去取代“java.util包下的类”。例如用CopyOnWriteArrayList 来代替ArrayList。

    fail-fast产生原因: 在“线程a”在遍历arrayList过程中的某一时刻,“线程b”执行了,并且“线程b”删除了arrayList中的“节点A”。“线程b”执行remove()进行删除操作时,在remove()中执行了“modCount++”,此时modCount变成了N+1
    “线程a”接着遍历,当它执行到next()函数时,调用checkForComodification()比较“expectedModCount”和“modCount”的大小;而“expectedModCount=N”,“modCount=N+1”,这样,便抛出ConcurrentModificationException异常,产生fail-fast事件。

    从中,我们可以看出:

    (01) ArrayList继承于AbstractList,而CopyOnWriteArrayList没有继承于AbstractList,仅仅只是实现了List接口。
    (02) ArrayList的iterator()函数返回的Iterator是在AbstractList中实现的;而CopyOnWriteArrayList是自己实现Iterator。
    (03) ArrayList的Iterator实现类中调用next()时,会“调用checkForComodification()比较‘expectedModCount’和‘modCount’的大小”;但是,CopyOnWriteArrayList的Iterator实现类中,没有所谓的checkForComodification(),更不会抛出ConcurrentModificationException异常!

  • 相关阅读:
    linux 配置文件.conf 非打印字符出错的研究(一)
    Python:Relative import 相对路径 ValueError: Attempted relative import in non-package
    GitHub desktop 管理 gitee 私有库
    python enumerate ,range下标迭代
    everything http服务器局域网不能访问 // Windows evething http server connect timeout in lan
    python install jnius, sikuli ;Exception: Unable to determine JDK_HOME
    sublime3 自定义 修改 颜色主题 配色方案
    python K线 蜡烛图
    IOError: [Errno 22] invalid mode ('rb') or filename: ’u202a’ / 'xe2x80xaa’
    [资源]汇集最有用的PHP资源
  • 原文地址:https://www.cnblogs.com/mcahkf/p/8608468.html
Copyright © 2020-2023  润新知