copyonwritearraylist适用于高频读、极低频写的场景,读操作无锁直接访问volatile数组快照,写操作加锁复制全量数组;迭代器基于创建时快照,弱一致性且不抛concurrentmodificationexception。

CopyOnWriteArrayList 的读写分离机制天然适配高频读、极低频写的场景,核心在于“读不碰锁、写才加锁 + 复制快照”,无需额外设计就能实现无锁化读访问。
读操作全程无锁,直接访问 volatile 数组快照
底层用 volatile Object[] array 存储数据,所有读方法(get、size、contains、iterator())都只调用 getArray() 获取当前数组引用,然后直接读取——没有 synchronized,没有 lock,也没有 CAS 自旋。因为 volatile 保证了引用更新的可见性,任意线程读到的都是某个确定时刻的完整快照。
- 例如
list.get(0)就是(E) array[0],纯内存访问,O(1) - 迭代器构造时立即拷贝当前 array 引用,后续遍历完全与后续写操作隔离
- 即使写线程正在复制数组、替换引用,读线程仍稳定访问旧数组,不会卡顿或重试
写操作独占加锁 + 全量复制,但低频时不构成瓶颈
写方法(add、remove、set)统一走 ReentrantLock,确保同一时刻最多一个写线程执行。它先复制原数组(Arrays.copyOf),在副本上修改,再用 volatile 写将 array 引用指向新数组。
一款AI开发辅助工具,主要用于从 AI 编程会话日志(Clawdbot、Claude Code、Codex)中提取对话记录。该功能用于在用户要求导出提示词历史、会话日志或 `.jsonl` 格式的会话文件时使用,适合需要提升相关任务效率的用户。
- 写耗时 = 数组长度 × 元素拷贝开销 + 锁竞争时间
- 若列表长期稳定在几百或几千元素,且每分钟至多一次写入,复制开销可忽略
- 关键点:写期间不影响任何读,读吞吐量不下降,系统响应不抖动
迭代器天然支持弱一致性遍历,避免 ConcurrentModificationException
调用 iterator() 返回的是创建时刻的数组快照对象,遍历过程完全独立于后续所有修改。这使得日志轮转、配置广播、监听器通知等场景能安全并发读取。
- 遍历时其他线程
add("new"),当前迭代器看不到该元素,也不报错 - 迭代器自身不支持
remove(),调用直接抛UnsupportedOperationException,杜绝误操作 - 适合“只读消费”类逻辑,如监控线程定时 dump 当前全部监听器、推送服务批量拉取活跃客户端列表
典型落地示例:配置项缓存容器
假设系统加载一份全局开关配置(如 feature flags),启动后极少变更:
- 初始化:
CopyOnWriteArrayList<string> flags = new CopyOnWriteArrayList(List.of("login-v2", "pay-async"));</string> - 高频读(每毫秒多次):
if (flags.contains("pay-async")) { ... }—— 无锁、无竞争、无 GC 压力 - 极低频写(运维后台触发):
flags.add("report-realtime")—— 加锁复制一次,毫秒级完成 - 所有工作线程读到的仍是变更前快照,直到下次读取新引用;新请求自然过渡到新配置










