Java CoryOnWriteArrayList 实现

引言

本文着重介绍 Java 并发容器中 CoryOnWriteArrayList 的实现方式。更多相关文章和其他文章均收录于。

CopyOnWriteArrayList

CopyOnWriteArrayList 用于读场景远多于写场景的情况,它能够让读与读之间不互斥,读与写也不互斥,只有写与写之间才会互斥。它的思路也很简单,内部通过一个数组来维护数据,正常读数据时直接通过索引从数组中提取数据。

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

@SuppressWarnings("unchecked")
private E get(Object[] a, int index) {
          
   
    return (E) a[index];
}

/**
 * {@inheritDoc}
 *
 * @throws IndexOutOfBoundsException {@inheritDoc}
 */
public E get(int index) {
          
   
    return get(getArray(), index);
}

/**
 * Gets the array.  Non-private so as to also be accessible
 * from CopyOnWriteArraySet class.
 */
final Object[] getArray() {
          
   
    return array;
}

而写数据时,需要将整个数组都复制一遍,然后在新数组的末尾添加最新的数据。最后替换掉原来的数组,这样原来的数组就会被回收。很显然,这种实现方式在减小竞争的同时,承担了数据空间 * 2 的压力。

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

/**
 * 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;
        Object[] newElements = Arrays.copyOf(elements, len + 1);
        newElements[len] = e;
        setArray(newElements);
        return true;
    } finally {
          
   
        lock.unlock();
    }
}

/**
 * Sets the array.
 */
final void setArray(Object[] a) {
          
   
    array = a;
}

参考内容

[1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] [16] 《Java并发编程的艺术》 [17] 《实战 Java 高并发程序设计》 [18] [19] [20] [21] [22] [23] [24] [25] [26]

经验分享 程序员 微信小程序 职场和发展