欢迎学习解读JAVA源码专栏,在这个系列中,我将手把手带着大家剖析Java核心组件的源码,内容包含集合、线程、线程池、并发、队列等,深入了解其背后的设计思想和实现细节,轻松应对工作面试 。
这是解读Java源码系列的第三篇 , 将跟大家一起学习比较神秘的并发集合 - CopyOnWriteArrayList 。
引言上篇文章提到ArrayList不是线程安全的,而CopyOnWriteArrayList是线程安全的 。此刻我就会产生几个问题:
- CopyOnWriteArrayList初始容量是多少?
- CopyOnWriteArrayList是怎么进行扩容的?
- CopyOnWriteArrayList是怎么保证线程安全的?
简介CopyOnWriteArrayList是一种线程安全的ArrayList,底层是基于数组实现,不过该数组使用了volatile关键字修饰 。实现线程安全的原理是,“人如其名”,就是 Copy On Write(写时复制) , 意思就是在对其进行修改操作的时候 , 复制一个新的ArrayList , 在新的ArrayList上进行修改操作 , 从而不影响旧的ArrayList的读操作 。看一下源码中CopyOnWriteArrayList内部有哪些数据结构组成:
public class CopyOnWriteArrayList<E> implements List<E>, Randomaccess, Cloneable, java.io.Serializable { // 加锁 , 用来保证线程安全 final transient ReentrantLock lock = new ReentrantLock(); // 存储元素的数组 , 使用了volatile修饰 private transient volatile Object[] array; // 数组的get/set方法 final Object[] getArray() { return array; } final void setArray(Object[] a) { array = a; }}
CopyOnWriteArrayList的内部结构非常简单 , 使用ReentrantLock加锁,用来保证线程安全 。使用数组存储元素,数组使用volatile修饰,用来保证内存可见性 。当其他线程重新对数组对象进行赋值的时候,当前线程可以及时感知到 。初始化当我们调用CopyOnWriteArrayList的构造方法的时候,底层逻辑是怎么实现的?
List<Integer> list = new CopyOnWriteArrayList<>();
CopyOnWriteArrayList初始化的时候,不支持指定数组长度,接着往下看,就能明白CopyOnWriteArrayList为什么不支持指定数组长度 。public CopyOnWriteArrayList() { setArray(new Object[0]);}
初始化过程非常简单,就是创建了一个长度为0的数组 。添加元素再看一下往CopyOnWriteArrayList添加元素时,调用的
add()
方法源码实现:// 添加元素public boolean add(E e) { // 加锁,保证线程安全 final ReentrantLock lock = this.lock; lock.lock(); try { // 获取原数组 Object[] elements = getArray(); int len = elements.length; // 创建一个新数组 , 长度原数组长度+1 , 并把原数组元素拷贝到新数组里面 Object[] newElements = Arrays.copyOf(elements, len + 1); // 直接赋值给新数组末尾位置 newElements[len] = e; // 替换原数组 setArray(newElements); return true; } finally { // 释放锁 lock.unlock(); }}
添加元素的流程:- 先使用ReentrantLock加锁 , 保证线程安全 。
- 再创建一个新数组,长度是原数组长度+1,并把原数组元素拷贝到新数组里面 。
- 然后在新数组末尾位置赋值
- 使用新数组替换掉原数组
推荐阅读
- 姜黎黎真是美了一辈子,69岁穿衣极简仍优雅高级,到老都没大妈感
- 睡觉多梦怎么办
- 跳绳怎么练能跳更快?
- 皮肤最好的状态是什么?
- 手机电脑的芯片主要是由什么物质组成
- 双胞胎名字是一对成语 双胞胎女儿洋气名字
- 忽见陌头杨柳色下一句,悔教夫婿觅封侯的完整诗句是什么
- 怎么用QQ开通微信,为什么用QQ账号还是登录不上微信
- 章子怡还是朱丹?这次周一围用行动说明了一切
- 久未露面的赵薇现身机场,手臂伤疤明显疑被家暴,47岁活像是个60岁大妈