CopyOnWriteArrayList是“读写分离”的容器,在写的时候是先将底层源数组复制到新数组中,然后在新数组中写,写完后更新源数组。而读只是在源数组上读。也就是,读和写是分离的。由于,写的时候每次都要将源数组复制到一个新组数中,所以写的效率不高。故而,CopyOnWriteArrayList适合并发读多于写的场景。

一:写时与读分离,但是也要加锁

“读写分离”的实现是通过在写时对原数组进行拷贝,然后在拷贝数组上写,而期间的读是读原数组。但是在写的时候需要加锁,不能并发写,因为如果多线程同时修改的话最终更新回原数组时就会发生竞态条件。

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

二:写时读,直接在原数组读,读的是旧数据,期间所作的更新还没设置回原数组,所以是不可见的

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

三:优缺点分析

优点:读写分离,在读多于写的并发操作场景下,极大地提升性能。

缺点:由写操作时复制原数组引起的内存占用问题;

由延时更新回原数组导致的一致性问题:只能保证最终一致性,即写后的新数组能设置为源数组,但不能保证实时一致性,即修改不能立刻被读到。如需要实时一致性的就不能用CopyOnWriteArrayList了。

Java并发容器——CopyOnWriteArrayList的更多相关文章

  1. Java并发编程原理与实战三十四:并发容器CopyOnWriteArrayList原理与使用

    1.ArrayList的实现原理是怎样的呢? ------>例如:ArrayList本质是实现了一个可变长度的数组. 假如这个数组的长度为10,调用add方法的时候,下标会移动到下一位,当移动到 ...

  2. Java并发编程系列-(5) Java并发容器

    5 并发容器 5.1 Hashtable.HashMap.TreeMap.HashSet.LinkedHashMap 在介绍并发容器之前,先分析下普通的容器,以及相应的实现,方便后续的对比. Hash ...

  3. java 并发容器一之BoundedConcurrentHashMap(基于JDK1.8)

    最近开始学习java并发容器,以补充自己在并发方面的知识,从源码上进行.如有不正确之处,还请各位大神批评指正. 前言: 本人个人理解,看一个类的源码要先从构造器入手,然后再看方法.下面看Bounded ...

  4. Java 并发系列之六:java 并发容器(4个)

    1. ConcurrentHashMap 2. ConcurrentLinkedQueue 3. ConcurrentSkipListMap 4. ConcurrentSkipListSet 5. t ...

  5. 《Java并发编程的艺术》第6/7/8章 Java并发容器与框架/13个原子操作/并发工具类

    第6章 Java并发容器和框架 6.1  ConcurrentHashMap(线程安全的HashMap.锁分段技术) 6.1.1 为什么要使用ConcurrentHashMap 在并发编程中使用Has ...

  6. 【java并发容器】并发容器之CopyOnWriteArrayList

    原文链接: http://ifeve.com/java-copy-on-write/ Copy-On-Write简称COW,是一种用于程序设计中的优化策略.其基本思路是,从一开始大家都在共享同一个内容 ...

  7. Java并发指南14:Java并发容器ConcurrentSkipListMap与CopyOnWriteArrayList

    原文出处http://cmsblogs.com/ 『chenssy』 到目前为止,我们在Java世界里看到了两种实现key-value的数据结构:Hash.TreeMap,这两种数据结构各自都有着优缺 ...

  8. java并发容器(Map、List、BlockingQueue)

    转发: 大海巨浪 Java库本身就有多种线程安全的容器和同步工具,其中同步容器包括两部分:一个是Vector和Hashtable.另外还有JDK1.2中加入的同步包装类,这些类都是由Collectio ...

  9. 多线程并发容器CopyOnWriteArrayList

    原文链接: http://ifeve.com/java-copy-on-write/ Copy-On-Write简称COW,是一种用于程序设计中的优化策略.其基本思路是,从一开始大家都在共享同一个内容 ...

随机推荐

  1. Android组件化方案

    Android组件化项目地址:Android组件化项目AndroidModulePattern Android组件化之终极方案地址:http://blog.csdn.net/guiying712/ar ...

  2. Oracle行列转换小结

    目录结构如下:行转列列转行[一].行转列 1.1.初始测试数据 表结构:TEST_TB_GRADE Sql代码 create table TEST_TB_GRADE (   ID        NUM ...

  3. 如何使用LaTeX让自己不乱?

    虽然说LaTeX声称排版容易,只关注内容,可是混合着源代码的结构很难让我只关注内容,最后看得眼睛疼,找什么都找不到. 匿名用户 30 人赞同 立即想到的几个建议: 选择有折叠功能 (folding) ...

  4. Ubuntu系统重启后/etc/resolv.conf内容丢失的解决方案

    通过resolvconf实现配置 resolvconfig应用可以实现DNS信息管理,可以通过下面的应用来安装此组件: sudo apt-get install resolvconf 创建/etc/d ...

  5. 总是容易忘记:enum、int、string之间的快速转换

    public enum Color { Red=, Green= } (1)Enum转换为String Color.Read.ToString() Convert.ToString(Color.Gre ...

  6. tcp常见状态

    常见状态 1.建立连接 2.关闭连接

  7. 第十一章 dubbo通信框架-netty4

    netty4是2.5.6引入的,2.5.6之前的netty用的是netty3.在dubbo源码中相较于netty3,添加netty4主要仅仅改了两个类:NettyServer,NettyClient. ...

  8. 卡卡游戏引擎之MVC模式下的事件处理

    前言 在前一篇文章 卡卡游戏引擎快速入门中提到了卡卡游戏引擎采用mvc的开发模式,这里相信介绍一下引擎在mvc模式下是如何做到低耦合的事件处理的. 在卡卡编辑器中选择一个节点,然后在左侧工具栏中切换到 ...

  9. 基于ZigBee和STM32的智能家居控制系统的设计与实现(三)

    基于ZigBee和STM32的智能家居控制系统的设计与实现(三) 自从前两篇博客介绍了智能家居系统的基本实现机理后,收到了好多朋友的来信,和我讨论了好多的这方面的知识,在此很高兴,虽然自己做的这个所谓 ...

  10. SharePoint2013 以其他用户登录和修改AD域用户密码 功能

    sharepoint默认是没有修改AD密码 和切换 用户的功能,这里我用future的方式来实现. 部署wsp前: 部署后: 点击以其他用户身份登录 点击修改用户密码: 这里的扩展才菜单我们用Cust ...