zoukankan      html  css  js  c++  java
  • 快速失败(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异常!

  • 相关阅读:
    BZOJ1045 [HAOI2008]糖果传递 && BZOJ3293 [Cqoi2011]分金币
    [BZOJ1103][POI2007]大都市meg dfs序+树状数组
    [BZOJ1122][POI2008]账本BBB 单调队列+后缀和
    [BZOJ1131][POI2008]Sta
    [BZOJ1370][Baltic2003]Gang团伙 并查集+拆点
    网易云基于 Kubernetes 的深度定制化实践
    微服务化的基石——持续集成
    微服务的接入层设计与动静资源隔离
    从互联网+角度看云计算的现状与未来(2)
    从互联网+角度看云计算的现状与未来(1)
  • 原文地址:https://www.cnblogs.com/mcahkf/p/8608468.html
Copyright © 2011-2022 走看看