JAVA并发包类|JAVA并发包类 - CopyOnWriteArrayList
说明:以下内容皆属于个人对源码的理解,可能存在歧义、误解、错误及理解不全面的情况,还望指正
一、CopyOnWriteArrayList介绍
CopyOnWriteArrayList是ArrayList的线程安全变体。底层通过创建数组的新副本来实现并发情况下对数组的更新操作(包括add、set等方法)。这种方式通常是花费代价比较大的,但是当遍历操作远大于更新操作的情况时,这种方式却是更有效的。当然,我们需要避免并发线程之间的干扰。CopyOnWriteArrayList允许添加所有的元素,包括Null。
【JAVA并发包类|JAVA并发包类 - CopyOnWriteArrayList】内存一致性效果:与其他并发集合一样,将对象放入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)方法
调用CopyOnWriteArrayList的add()方法时,首先会用ReentranctLock实例的lock()方法获取锁,然后获取底层数组对象并将底层数组对象拷贝到一个新的数组对象中,将要添加的元素添加到新的数组对象中,最后调用setArray方法,将底层数组对象变量array引向新的数组对象。最后释放锁。 - iterator()方法
iterator()方法其实是在内部创建了一个COWIterator实例对象,在该实例对象的内部声明一个数组的快照变量指向CopyOnWriteArrayList的底层数组。然后通过该变量进行对数组元素的遍历操作。与iterator()方法类似的还有sublist()方法。 - 其它方法
CopyOnWriteArrayList的其它的更新操作基本与add()方法思想一直,都是先获取锁,在操作完成后将原有数组变量指向新的数组变量。最后在finally块中释放锁。
推荐阅读
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- 事件代理
- Java|Java OpenCV图像处理之SIFT角点检测详解
- java中如何实现重建二叉树
- 数组常用方法一
- 【Hadoop踩雷】Mac下安装Hadoop3以及Java版本问题
- Java|Java基础——数组
- RxJava|RxJava 在Android项目中的使用(一)
- java之static、static|java之static、static final、final的区别与应用
- 抱怨并没有任何意义