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异常!

  • 相关阅读:
    ibatis 中isNull, isNotNull与isEmpty, isNotEmpty区别
    关于异常Microsoft.CSharp.RuntimeBinder.RuntimeBinderException
    php 利用fsockopen GET/POST 提交表单及上传文件
    php发送get、post请求获取内容的几种方法
    修改WampServer的默认端口
    SQL Server2008附加数据库之后显示为只读时解决方法
    Linux一键安装web环境全攻略(阿里云服务器)
    如何从Windows远程上传文件到Linux(例如CentOS 7)
    在CentOS上搭建PHP服务器环境
    linux(系统centos6.5)常用命令总结
  • 原文地址:https://www.cnblogs.com/mcahkf/p/8608468.html
Copyright © 2011-2022 走看看