Java并发 - COW容器

0. COW是什么

COW:Copy On Write写时复制,并发的一种优化策略。
当多个线程访问某共享资源时,如果其中一个线程需要更改资源内容,不直接在原资源上修改,而是复制出来一份,修改复制品,然后更新资源。
应用了读写分离的思想,读和写在不同的对象上进行。

1. 实现原理

CopyOnWriteArrayList为例,CopyOnWriteArraySet是用前者实现的,但是在添加元素时会遍历检查当前数组中有无该元素:
读时直接访问,没有同步策略:

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

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

写时复制原对象到一个新的对象,修改在新对象上进行,然后更新原对象:

/**
 * 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();
    }
}

2. 应用场景

根据其原理我们可以知道:

  • 更改资源会增加资源开销(与数据规模成正比)
  • 数据更新非实时,但会保持最终一致性

所以其使用场景为不要求实时性的读多写少的并发场景

3. 参考

  1. CopyOnWriteArrayList源码build 1.8.0_121-b13版本
  2. 聊聊并发-Java中的Copy-On-Write容器
  3. 线程安全的CopyOnWriteArrayList介绍
  4. JAVA中的COPYONWRITE容器

你可能感兴趣的:(Java并发 - COW容器)