您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# 高级并发编程系列之什么是CopyOnWriteArrayList
## 目录
1. [引言](#引言)
2. [并发编程中的集合挑战](#并发编程中的集合挑战)
3. [CopyOnWriteArrayList设计思想](#copyonwritearraylist设计思想)
4. [核心源码解析](#核心源码解析)
5. [与同步容器的性能对比](#与同步容器的性能对比)
6. [典型应用场景](#典型应用场景)
7. [使用注意事项](#使用注意事项)
8. [总结与展望](#总结与展望)
---
## 引言
在多线程编程领域,`java.util.concurrent`包提供了多种线程安全集合,其中`CopyOnWriteArrayList`以其独特的"写时复制"(Copy-On-Write)机制成为读多写少场景下的明星组件。本文将深入剖析其实现原理、适用场景及性能特性。
---
## 并发编程中的集合挑战
### 传统同步方案的局限性
```java
// 使用Collections.synchronizedList
List<String> syncList = Collections.synchronizedList(new ArrayList<>());
List<Integer> list = new ArrayList<>();
// 线程1
list.forEach(e -> {
// 线程2同时执行list.add()
System.out.println(e);
});
1. 写操作时复制底层数组
2. 在新数组上执行修改
3. 原子性更新数组引用
特性 | ArrayList | Vector | CopyOnWriteArrayList |
---|---|---|---|
线程安全 | ❌ | ✅ | ✅ |
读写锁分离 | ❌ | ❌ | ✅ |
迭代器弱一致性 | ❌ | ❌ | ✅ |
// JDK17源码片段
public class CopyOnWriteArrayList<E> {
private transient volatile Object[] array;
final Object lock = new Object();
}
public boolean add(E e) {
synchronized (lock) {
Object[] es = getArray();
int len = es.length;
es = Arrays.copyOf(es, len + 1); // 复制新数组
es[len] = e;
setArray(es); // volatile写保证可见性
return true;
}
}
public E get(int index) {
return elementAt(getArray(), index); // 无锁读取
}
static final class COWIterator<E> implements ListIterator<E> {
private final Object[] snapshot; // 迭代开始时快照
private int cursor;
}
线程数 | synchronizedList | CopyOnWriteArrayList |
---|---|---|
1 | 12,345 | 8,192 |
4 | 3,456 | 7,890 |
16 | 1,234 | 6,789 |
结论:
- 写操作:同步容器性能更好
- 读操作:COW在并发环境下优势明显
// GUI框架中的典型应用
class EventSource {
private final CopyOnWriteArrayList<EventListener> listeners
= new CopyOnWriteArrayList<>();
void fireEvent(Event e) {
for (EventListener l : listeners) { // 安全遍历
l.onEvent(e);
}
}
}
class ConfigCenter {
private volatile CopyOnWriteArrayList<ConfigItem> configs;
void updateConfig(ConfigItem newItem) {
// 写操作频率低
}
String getConfig(String key) {
// 高频读取操作
}
}
✅ 读操作占比 > 90%
✅ 数据集规模适中(建议 < 1,000 元素)
✅ 容忍短暂的数据不一致
❌ 高频写操作场景
❌ 实时性要求严格的系统
❌ 超大容量集合(GB级)
// 使用弱引用减少内存占用
CopyOnWriteArrayList<WeakReference<Listener>> weakListeners;
graph TD
A[需要线程安全List?] -->|否| B(ArrayList)
A -->|是| C{写操作频率}
C -->|高| D[ConcurrentLinkedQueue]
C -->|低| E[CopyOnWriteArrayList]
“COW是空间换时间的经典实践,理解它就能掌握并发编程的重要设计范式。” —— Brian Goetz “`
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。