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容器
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1.ios高性能编程 (1).内层 最小的内层平均值和峰值(2).耗电量 高效的算法和数据结构(3).初始化时...
    欧辰_OSR阅读 29,656评论 8 265
  • Java SE 基础: 封装、继承、多态 封装: 概念:就是把对象的属性和操作(或服务)结合为一个独立的整体,并尽...
    Jayden_Cao阅读 2,156评论 0 8
  • Java-Review-Note——4.多线程 标签: JavaStudy PS:本来是分开三篇的,后来想想还是整...
    coder_pig阅读 1,683评论 2 17
  • 最近在整理安卓的课件,整理出来供大家参考 1.前世 企鹅 Android 是基于Linux的低层代码搭建起来的。当...
    Doria2016阅读 1,559评论 0 6
  • 可能是对自己的要求越来越高,我对写作产生了恐惧心理。 我看书看电影看纪录片,整理的笔记和素材不少,记录的灵感也挺多...
    作家二美阅读 664评论 13 17