集合的快速失败机制

2018-08-09  本文已影响0人  mrjunwang

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
上一篇下一篇

猜你喜欢

热点阅读