CopyOnWriteArrayList实现原理源码分析

本文深入探讨了CopyOnWriteArrayList的实现原理,分析了其与ArrayList和Vector的区别。CopyOnWriteArrayList通过写时复制(COW)策略确保线程安全,避免了Vector的同步锁导致的性能问题。在添加和移除元素时,它利用ReentrantLock和volatile保证并发安全,并在读取操作中提供高性能。此外,文章还讨论了其容量管理机制和内存可见性。
摘要由CSDN通过智能技术生成

针对于并发场景下动态数组的选型,可以使用线程安全的列表Vector,Vector是jdk1.0版本就带有的一个线程安全的动态数组类,但是Vector的实现原理之前分析过,对于所有对内部存储数据结构的操作,都添加了同步锁,这样的实现方式,虽然保证了线程的安全性,大并发场景下,却等同于多个线程的串行化执行,效率低下。jdk1.5引入了新的线程安全的列表实现CopyOnWriteArrayList。

一、CopyOnWriteArrayList的实现类图

类图结构和ArrayList完全一致,这个也合理,从CopyOnWriteArrayList名称上看,它是一种特殊的ArrayList。

同ArrayList直接实现了了四个接口如上,其中List提供了基础的添加、删除、遍历操作;

RandomAccess提供了随机访问能力、Cloneable接口,提供了可以被克隆、Serializable接口,提供了可以序列化的能力;

RandomAccess、Cloneable、Serializable都是空接口,这种空接口在Jdk的机制中,这种标记接口被实现后,起到给类打标记的作用,程序在运行期间通过识别标记,实现相应的功能。当然有兴趣了解更多标记接口的实现和运行机制,可以查阅相关其它资料。

接下来,我们通过阅读源码看代码底层的数据结构的实现、扩容机制上的区别、是否线程安全、以及性能优势。

二、源码分析

内部数据结构对象的声明部分:

/** 保护所有增变基因的锁 */
final transient ReentrantLock lock = new ReentrantLock();

/** 私有的 内部数组 被volatile关键字修饰 */
private transient volatile Object[] array;

内部数据结构的声明部分比ArrayList要简单,仅仅一个数组的声明,但是不同的是有一个ReentrantLock锁。

lock:ReentrantLock独占锁,多线程运行下,只有一个线程可以获得这个锁,只有释放锁后其他线程才能获得。

array:存放数据的数组,关键是被volatile修饰了,保证了可见性,也就是一个线程修改后,其他线程立即可见。

看一下构造函数:

/**
 * 创建一个空列表
 */
public CopyOnWriteArrayList() {
   
    setArray(new Object[0]);
}
/**
  * 声明的成员变量,只能被setArray()、getArray()访问
  */
 final void setArray(Object[] a) {
   
     array = a;
}

setArray()、getArray()方法,都final关键字修饰,方法无法被重写,确定了内部封装性。

/**
 * 获取列表的大小
 * @return the number of elements in this list
 */
public int size() {
   </
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hymKing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值