Java并发工具:CopyOnWriteArrayList
CopyOnWriteArrayList 是 Java 中 java.util.concurrent 包提供的一种线程安全的 List 实现。它特别适用于读多写少(Read-mostly)的并发场景,比如事件监听器列表、配置管理等。
核心思想
- 写时复制(Copy-On-Write)
每当对集合进行修改操作(如添加、删除、替换元素)时,它会创建一个新的数组副本,并在新副本上执行修改操作,最后再将引用指向新的数组。
而读取操作(如 get, iterator 等)不会加锁,直接访问当前数组。
- 线程安全实现
通过 volatile 关键字修饰底层数组,保证可见性;写操作通过锁(ReentrantLock)实现互斥。
每次写操作生成新数组,避免并发写冲突,但可能短暂存在多个数组副本。
特点
| 特性 | 描述 | 
| 线程安全 | 所有操作都是线程安全的,不需要外部同步 | 
| 写操作加锁 | 修改操作(add, set, remove)使用重入锁(ReentrantLock)保护 | 
| 读不加锁 | 读操作无锁,性能高 | 
| 最终一致性 | 迭代器或快照视图看到的是创建那一刻的数据状态 | 
| 高开销写操作 | 每次写都要复制整个数组,适合写少读多的场景 | 
| 不抛出  | 因为迭代基于快照 | 
常用方法示例
import java.util.concurrent.CopyOnWriteArrayList;
public class CpListExample {
    public static void main(String[] args) {
        CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
        // 添加元素
        list.add("A");
        list.add("B");
        list.add("C");
        // 读取元素
        System.out.println(list.get(0));  // 输出 A
        // 删除元素
        list.remove("B");
        // 遍历(不会抛出 ConcurrentModificationException)
        for (String s : list) {
            System.out.println(s);
        }
    }
}
内部原理简析
1. 内部维护一个 volatile transient Object[] array; 来保存数据。
2. 每次写操作都会复制原数组到新数组并修改新数组。
3. 使用 ReentrantLock 来保证写操作的原子性和可见性。
4. 读操作直接访问 array,因为 volatile 能确保可见性。
适用场景
适合场景:
- 大量读操作,少量写操作
- 对实时一致性要求不高(最终一致即可)
不适合场景:
- 写操作频繁
- 数据量大(每次写都复制数组,性能差)
注意事项
- 内存开销:频繁写操作会导致大量数组复制,可能引发内存和 GC 压力。
- 实时性不足:读操作可能获取旧数据,不适合强一致性场景。
- 迭代器限制:迭代器不支持修改操作(如 remove、set),调用会抛出 UnsupportedOperationException。
与 Vector / Collections.synchronizedList 对比
| 特性 | Vector | Collections.synchronizedList | CopyOnWriteArrayList | 
| 线程安全 | 是 | 是 | 是 | 
| 读写是否加锁 | 读写都加锁 | 读写都加锁 | 仅写加锁 | 
| 并发性能 | 差 | 一般 | 好(读并发强) | 
| 是否抛 CME | 否 | 是 | 否 | 
| 是否支持快照遍历 | 否 | 否 | 是 | 
相关文章
- Spring Boot中对接Twilio以实现发送验证码和验证短信码
- Spring Boot 3.5:这次更新让你连配置都不用写了,惊不惊喜?
- Spring Boot+Pinot实战:毫秒级实时竞价系统构建
- SpringBoot敏感配置项加密与解密实战
- SpringBoot 注解最全详解,建议收藏!
- Spring Boot 常用注解大全:从入门到进阶
- SpringBoot启动之谜:@SpringBootApplication如何让配置化繁为简
- Springboot集成Kafka原理_spring集成kafka的原理
- Spring Boot中@Data注解的深度解析与实战应用
- 大佬用1000字就把SpringBoot的配置文件讲的明明白白!

