copyonwritearraylist通过写时复制实现读写分离:读操作无锁访问volatile数组,写操作加锁复制新数组并原子更新引用,适合读多写少场景。

CopyOnWriteArrayList 通过“写时复制”机制实现读写分离,本质是读操作无锁、写操作加锁并复制新数组。
读操作不加锁,直接访问当前数组
每次读取(如 get()、iterator()、size())都直接操作内部的 volatile 数组引用,无需同步。由于数组本身不可变(内容固定),多个线程可同时安全读取,不会相互阻塞。
注意:迭代器返回的是创建时刻的快照,后续写操作不影响已生成的迭代器 —— 这也是“弱一致性”的来源。
写操作加锁 + 复制新数组 + 原子更新引用
所有修改方法(如 add()、remove()、set())都先获取独占锁(ReentrantLock),然后:
- 拷贝当前数组到新数组
- 在新数组上完成修改
- 用 volatile 写语义将内部数组引用指向新数组
这个过程保证了写操作的原子性,也确保读操作总能看到某个完整快照,不会读到“半更新”的中间状态。
volatile 引用是读写可见性的关键
内部数组被声明为 volatile Object[] array。写操作更新引用时,能立即对其他线程可见;读操作读取该引用时,也能看到最新写入的数组地址。这避免了加锁读,又保障了读到的是某次写完成后的完整副本。
适合读多写少且不要求强一致性的场景
因为每次写都要复制整个数组,时间与空间开销随元素数量线性增长,所以:
- 适用于读操作远多于写操作(比如监听器列表、配置缓存)
- 不适合频繁写或大数据量(如万级元素高频增删)
- 不保证实时一致性:读线程可能看不到最近一次写的结果(最多延迟一个写操作)
它不是传统意义上的“分离读写线程”,而是用空间换并发安全 —— 用复制代价消除读写互斥。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











