并发工具类 CopyOnWriteArrayList

一、高效读取CopyOnWriteArrayList

由于读操作根本不会修改原有的数据,因此对于每次读取操作都进行加锁其实是一种资源浪费。 应该允许多个线程同时访问List的内部数据,毕竟是安全的。根据读写锁的思想,读与读之间不冲突,但是读操作会受到写操作的影响,当发生写操作时,读就必须等待,否则可能读到不一致的数据。同理,如果读操作正在进行,程序也不能进行写入。


1.1 CopyOnWriteArrayList

对于这个类,读取完全不加锁,并且写入也不会阻塞读取操作,只是写入和写入之间需要进行同步等待。

其实现原理。就是在写入操作时,进行一次自我复制。将修改的内容写入副本中。写完之后,再将修改完的副本替换原来的数据。这样可以保证写操作不会受影响。

1.2 源码分析

public class CopyOnWriteArrayList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
    private transient volatile Object[] array; //volatile关键字修饰,可见性

    /**
     * 读操作不加锁
     */
    public E get(int index) {
        return get(getArray(), index);
    }
   final Object[] getArray() {
        return array;
    }

    /**
     * 写操作需要加锁
     */
    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);//用新数组替换老数组。修改完成。数组为volatile修饰。
            return true;
        } finally {
            lock.unlock();
        }
    }

}

参考

  1. 《实战java高并发程序设计》

猜你喜欢

转载自blog.csdn.net/qq_31156277/article/details/80640186