CopyOnWriteArrayList原理与适用场景
请解释CopyOnWriteArrayList的工作原理、优缺点以及适用的并发场景。
回答
小字辈
原理:
- 读写分离:读取时不加锁,直接读取内部数组。
- 写入(add/set/remove)时:先加锁(ReentrantLock),复制一个新数组(长度+1),在新数组上修改,然后将volatile的array引用指向新数组。
- 读取操作完全无锁,性能极高。
核心源码:
public boolean add(E e) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
Object[] newElements = Arrays.copyOf(elements, len + 1);
newElements[len] = e;
setArray(newElements);
return true;
} finally { lock.unlock(); }
}
优缺点: | 优点 | 缺点 | |------|------| | 读操作无锁,高并发读性能好 | 写操作需要复制整个数组,内存开销大 | | 迭代器弱一致性(不抛ConcurrentModificationException)| 写操作成本高(复制),不适合频繁写场景 | | 读写不互斥 | 数据最终一致性,不保证实时可见 |
适用场景:读多写少、集合大小较小、数据一致性要求不严格的场景(如白名单、配置缓存、事件监听器列表)。