美文网首页
盘点CopyOnWriteArrayList与ArrayList

盘点CopyOnWriteArrayList与ArrayList

作者: 码农MM | 来源:发表于2019-07-26 16:49 被阅读0次

    2. CopyOnWriteArrayList

    CopyOnWriteArrayList是什么呢?顾名思义,先Copy后Write(将原来的array复制到新的array),也就是说对于CopyOnWriteArrayList,任何可变的操作(add、set、remove等等)都是通过ReentrantLock 控制并发并伴随复制这个动作。

    看一下add操作怎么实现的

    public boolean add(E e) {
        final ReentrantLock lock = this.lock;
        //获得锁
        lock.lock();
        try {
            Object[] elements = getArray();
            int len = elements.length;
            //复制一个新的数组
            Object[] newElements = Arrays.copyOf(elements, len + 1);
            //插入新值
            newElements[len] = e;
            //将新的数组指向原来的引用
            setArray(newElements);
            return true;
        } finally {
            //释放锁
            lock.unlock();
        }
    }
    

    看完明白了,上个锁自己复制、修改、赋值嘛,这就厉害了,Vector是增删改查方法都加了synchronized,保证同步,但是每个方法执行的时候都要去获得锁,性能就会大大下降,而CopyOnWriteArrayList 只是在增删改上加锁,但是读不加锁,在读方面的性能就好于Vector,CopyOnWriteArrayList支持读多写少的并发情况,快快试一下先:

         CopyOnWriteArrayList<String> copyOnWriteArrayList = new CopyOnWriteArrayList();
            for (int i = 1; i < 6; i++) {
                copyOnWriteArrayList.add("测试" + i);
            }
            for (String strCopyList : copyOnWriteArrayList) {
                copyOnWriteArrayList.remove("测试2");
                Log.d(TAG, "---strCopyList---" + strCopyList);
                Log.d(TAG, "---copyOnWriteArrayList---" + copyOnWriteArrayList);
            }
    

    执行结果:


    执行结果

    可以看出list的数据已经改变了,但是遍历的结果为什么“测试2”还在?这就是因为他copy的原因,实际的list数据已经改变了,但是此次遍历的数据还是之前的list,所以导致此现象。

    相关文章

      网友评论

          本文标题:盘点CopyOnWriteArrayList与ArrayList

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