美文网首页
集合的快速失败机制

集合的快速失败机制

作者: mrjunwang | 来源:发表于2018-08-09 10:32 被阅读0次

    Java集合的快速失败机制 “fail-fast”?

    答:

    是java集合的一种错误检测机制,当多个线程对集合进行结构上的改变的操作时,有可能会产生 fail-fast 机制。

    例如:假设存在两个线程(线程1、线程2),线程1通过Iterator在遍历集合A中的元素,在某个时候线程2修改了集合A的结构(是结构上面的修改,而不是简单的修改集合元素的内容),那么这个时候程序就会抛出 ConcurrentModificationException 异常,从而产生fail-fast机制。

    原因:迭代器在遍历时直接访问集合中的内容,并且在遍历过程中使用一个 modCount 变量。集合在被遍历期间如果内容发生变化,就会改变modCount的值(无论是add()、remove(),还是clear(),只要涉及到修改集合中的元素个数时,都会改变modCount的值)。每当迭代器使用hashNext()/next()遍历下一个元素之前,都会检测modCount变量是否为expectedmodCount值,是的话就返回遍历;否则抛出异常,终止遍历。

    解决办法:

    1. 在遍历过程中,所有涉及到改变modCount值得地方全部加上synchronized。

    2. 使用CopyOnWriteArrayList来替换ArrayList
      3.如果使用vector替换arraylist,仍会报currentModificationException
      Vector源码可以发现它的很多方法都加上了synchronized来进行线程同步,例如add()、remove()、set()、get(),但是Vector内部的synchronized方法无法控制到遍历操作,所以即使是线程安全的Vector也无法做到线程安全地遍历。

    如果想要线程安全地遍历Vector,需要我们去手动在遍历时给Vector加上synchronized锁,

    并发容器支持并发的遍历和并发的更新。

    主要的类有ConcurrentHashMap, CopyOnWriteArrayList 和CopyOnWriteArraySet

    public class DelArrayList<E> {
        
    
        public static List<Integer> list=new ArrayList<>();
        public DelArrayList(){
            for(int i=0;i<6;i++){
                list.add(i);
                
            }
        }
    
        /**
         * @param args
         *            <p>
         *            Description:
         *            </p>
         */
            private static class ThreadA extends Thread{
            
            public void run(){
                
                Iterator it=list.iterator();
                while(it.hasNext()){
                    System.out.println(it.next());
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                    
                        
            }
        }
        
        private static class ThreadB implements Runnable{
    
            /* (non-Javadoc)
             * @see java.lang.Runnable#run()
             */
            
            @Override
            public void run() {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                    list.remove(2);
    
            }
            
        }
    
    image.png

    相关文章

      网友评论

          本文标题:集合的快速失败机制

          本文链接:https://www.haomeiwen.com/subject/wcdqbftx.html