JAVA并发包类 - CopyOnWriteArrayList

说明:以下内容皆属于个人对源码的理解,可能存在歧义、误解、错误及理解不全面的情况,还望指正

一、CopyOnWriteArrayList介绍

CopyOnWriteArrayListArrayList的线程安全变体。底层通过创建数组的新副本来实现并发情况下对数组的更新操作(包括add、set等方法)。这种方式通常是花费代价比较大的,但是当遍历操作远大于更新操作的情况时,这种方式却是更有效的。当然,我们需要避免并发线程之间的干扰。CopyOnWriteArrayList允许添加所有的元素,包括Null

内存一致性效果:与其他并发集合一样,将对象放入CopyOnWriteArrayList之前的线程中的动作发生在另一个线程的CopyOnWriteArrayList中访问或删除该元素之后的操作之前。

二、CopyOnWriteArrayList实现

  • 构造函数
    CopyOnWriteArrayList提供了三个构造函数:默认的构造函数,传入指定集合的构造函数,将指定数组拷贝到CopyOnWriteArrayList的构造函数。目前只了解一下默认构造函数的实现。
    CopyOnWriteArrayList在调用构造函数实例化对象的时候,会创建一个大小为0的数组对象,将CopyOnWriteArrayList底层的数组对象变量指向这个数组。这个对象变量在源码中的定义如下:
/** The array, accessed only via getArray/setArray. */
private transient volatile Object[] array;

底层数组变量array被声明为volatile 类型的,这样在对数组进行遍历的时候获取的都是最新的值。那么并发访问数据遍历的问题就得以解决。
在创建
CopyOnWriteArrayList
对象实例时,同时会创建一个ReentranctLock的实例。

  • add(E e)方法
    调用CopyOnWriteArrayListadd()方法时,首先会用ReentranctLock实例的lock()方法获取锁,然后获取底层数组对象并将底层数组对象拷贝到一个新的数组对象中,将要添加的元素添加到新的数组对象中,最后调用setArray方法,将底层数组对象变量array引向新的数组对象。最后释放锁。
  • iterator()方法
    iterator()方法其实是在内部创建了一个COWIterator实例对象,在该实例对象的内部声明一个数组的快照变量指向CopyOnWriteArrayList的底层数组。然后通过该变量进行对数组元素的遍历操作。与iterator()方法类似的还有sublist()方法。
  • 其它方法
    CopyOnWriteArrayList的其它的更新操作基本与add()方法思想一直,都是先获取锁,在操作完成后将原有数组变量指向新的数组变量。最后在finally块中释放锁。

三、CopyOnWriteArrayList总结

CopyOnWriteArrayList的实现,可以看出包含了2个思想:读写分离和最终一致性(因为并发访问情况下,某个线程作了元素的更新操作后,array变量尚未指向新数组前,其它线程访问的可能还是原来的数组里的元素)。对于多线程情况下,遍历访问操作远大于更新操作的时候,CopyOnWriteArrayList无疑是最好的选择,省略了我们自己去加同步的操作。但是数组的拷贝是一项费时费资源的操作,对于非多线程或数据变化较多的情况下,还是避免使用。

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

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,765评论 18 399
  • 一:java概述:1,JDK:Java Development Kit,java的开发和运行环境,java的开发工...
    ZaneInTheSun阅读 2,687评论 0 11
  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,366评论 11 349
  • 今天中午几个同事一起在食堂用餐,谈到近期饮品类加盟店“一点点”雨后春笋般铺开的现象。已有同事想集资开一家店。 集资...
    马努塔阅读 140评论 0 0
  • 文/小楠 “你真的在听我说话吗?” 在我和老公吵架的时候,这是出现频率最高的一句话。 有一天晚上吵到凌晨三点,室友...
    个人成长教练周育楠阅读 1,223评论 0 1