The principle CopyOnWriteArrayList

Copyright Notice: Copyright: This article is a blogger original article, shall not be reproduced without the bloggers allowed. https://blog.csdn.net/qq_37598011/article/details/90404496

    CopyOnWriteArrayList is a concurrent Java container and contract provided, it is a thread-safe ArrayList , the write operation is achieved by creating a new copy of the underlying array is a separate read and write concurrency strategy, we can call this container " when writing replicator ", Java and contract in similar containers also CopyOnWriteSet, but in CopyOnWriteSet any natural calling is CopyOnWriteArrayList.

The principle

    Collection framework ArrayList is non-thread-safe, the Vector though it is thread-safe, but it's very simple lock synchronization mechanism so poor performance. And CopyOnWriteArrayList provides a different kind of concurrent treatment strategy ( separate read and write ).

 CopyOnWriteArrayList containers allow concurrent read, the read operation is no lock, higher performance. For write operations, such as adding an element to the vessel, the first copy of the current container, and then perform a write operation on the new copy, then the original container after the end of a reference point to the new container.

    /** The lock protecting all mutators */
    final transient ReentrantLock lock = new ReentrantLock();

    /** The array, accessed only via getArray/setArray. */
    private transient volatile Object[] array;


    /**
     * Appends the specified element to the end of this list.
     *
     * @param e element to be appended to this list
     * @return {@code true} (as specified by {@link Collection#add})
     */
    public boolean add(E e) {
        //获取锁
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            //获取原数组
            Object[] elements = getArray();
            //获取原数组个数
            int len = elements.length;
            //拷贝一份原数组并+1,生成的新数组的len位置上增加元素
            Object[] newElements = Arrays.copyOf(elements, len + 1);
            newElements[len] = e;
            //替换原数组
            setArray(newElements);
            return true;
        } finally {
            //释放锁
            lock.unlock();
        }
    }

    We can see it in the new element of time acquires a lock and then generate a new array +1, this time adding new elements and then add the location of the new array, and finally replace the original array on the line.

   public E remove(int index) {
        //获取锁
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            //获取原数组,并得出当前数组大小
            Object[] elements = getArray();
            int len = elements.length;
            //获取旧值,并计算索引位置
            E oldValue = get(elements, index);
            int numMoved = len - index - 1;
            //表示是末尾,直接拷贝原数组0-(len-1)
            if (numMoved == 0)
                setArray(Arrays.copyOf(elements, len - 1));
            else {
                //生成新数组并进行两次拷贝
                Object[] newElements = new Object[len - 1];
                System.arraycopy(elements, 0, newElements, 0, index);
                System.arraycopy(elements, index + 1, newElements, index,
                                 numMoved);
                setArray(newElements);
            }
            return oldValue;
        } finally {
            //解锁
            lock.unlock();
        }
    }

    Deletion Similarly, other elements other than the element to be deleted is copied to the new array, and then switch references the original array reference point to the new array. Belong to write, you need to lock.

public E get(int index) {
        return get(getArray(), index);
    }

     Gets the element need not locked.

Advantages and disadvantages

advantage:

  1. CopyOnWriteArrayList Because of its " write isolated " thinking, and modify operations are traversing acting different arrays so iterators to traverse, it does not throw ConcurrentModificationException exception.
  2. Read performance is very high, because without any synchronization measures, more suitable for reading and writing less concurrent scene.

Disadvantages:

  1. Memory footprint issue , each time a write operation to be a copy of the original container, when the large amount of data to memory pressure, may cause frequent GC.
  2. Can not guarantee the timeliness , Vector lock for read and write operations are synchronized, you can ensure strong consistency read and write. The CopyOnWriteArrayList implementation strategy is to write and read, respectively, on a different role in an array of new and old, during a write operation is performed, the read will not block but it is read to the updated data is.

 

Guess you like

Origin blog.csdn.net/qq_37598011/article/details/90404496