盘点CopyOnWriteArrayList与ArrayList

2019-07-26  本文已影响0人  码农MM

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,所以导致此现象。

上一篇 下一篇

猜你喜欢

热点阅读