知识卡片

写时复制偏向读

普通读书笔记卡 · 1532

内容

CopyOnWriteArrayList 内部持有指向底层数组的 volatile 引用 array;写操作先复制一份新数组、在副本上改,改完再把 array 切到新数组,原数组回收。读操作直接访问当前数组,不需要加锁——要么读到修改前的完整旧数组,要么读到修改后的完整新数组,迭代也不受并发写打断。代价是写要整体复制,只适合读远多于写、数据规模可控的场景。

参考来源

- 位置:《Java高并发核心编程.卷2,多线程、锁、JMM、JUC、高并发设计模式》第7章《JUC容器类》7.3.2节《CopyOnWriteArrayList的原理》(源文件:_epub-src/OEBPS/Text/chapter234.xhtml) - 结论依据:原文说明“可变操作(add、set等)是在array数组的副本上进行的。当元素需要被修改或者增加时,并不直接在array指向的原有数组上操作,而是首先对array进行一次复制,将修改的内容写入复制的副本中。写完之后,再将内部指针array指向新的副本,这样就可以确保修改操作不会影响访问器的读取操作”,因此推出本卡结论。 - 原始内容:当元素需要被修改或者增加时,并不直接在array指向的原有数组上操作,而是首先对array进行一次复制,将修改的内容写入复制的副本中。写完之后,再将内部指针array指向新的副本,这样就可以确保修改操作不会影响访问器的读取操作。