有一天,我和 CopyOnWriteArrayList 杯“线程安全”的咖啡

原文来自于:[zha-ge.cn/java/38](https://link.juejin.cn?target=https%3A%2F%2Fzha-ge.cn%2Fjava%2F38 "https://zha-ge.cn/java/38")zha-ge.cn/java/38)

有一天,我和 CopyOnWriteArrayList 杯"线程安全"的咖啡

"说出来你可能不信,我第一次遇见 CopyOnWriteArrayList,真有点像突然喝到了一杯奇葩口味咖啡。" 那天项目里一顿多线程操作 ArrayList,直接就炸了------各种 ConcurrentModificationException 扑面而来。眼看需求日期在逼近,我只能抱着百度拼命啃资料,终于,那个神秘的名字------CopyOnWriteArrayList,出现在我的面前。

奇怪的名字,神奇的用法

这货的名字一看就不走寻常路:"写时复制"列表。跟平时 ArrayList 那种你加我加大家抢着改的作风完全不一样。 CopyOnWriteArrayList 的大法简单粗暴:只要有修改操作,比如 add 或 remove,它就直接把底层的数组"复制"一份,改完再换上。 读的时候,全世界读线程用的都是一个老版本的新数组,根本不用加锁。 写的时候,悄咪咪整出个新副本,等你们都读完了再说。

代码长这样:

java 复制代码
CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
list.add("程序员");
list.add("出门左转");
list.remove("左转");
// ...

嗯,是不是看着很清爽? 连 iterator 都不用担心:

java 复制代码
for (String s : list) {
    System.out.println(s);
    // list.add("插队"); // 不会抛 ConcurrentModificationException
}

想当初用普通 ArrayList,改着改着分分钟爆炸。CopyOnWriteArrayList 则"稳如老狗"。

踩坑瞬间

说起来简单,真用的时候,坑也是多得想抽自己耳光。

  • 那天真有个需求,存个8万条数据要频繁 add/remove。本想 CopyOnWriteArrayList 线程安全,直接莽,结果垃圾回收疯狂爆发,内存飙升。
  • 遍历过程中,想试试能不能边遍历边加元素,嗯,是不会抛异常,结果新加的东西遍历完了也看不到......
  • 查文档的时候脑子一热:既然线程安全,啥场面都能用吧!后来 Leader 只说了三个字:"开除吧!"

经验启示

时间一久,我总结出一套"用 CopyOnWriteArrayList 的锦囊":

  • 适合读多写少场景 频繁写?直接 gg,别用这玩意儿,损失性能简直肉眼可见。
  • 遍历期间修改,遍历不到最新元素 它的 iterator 永远"活在过去"。要最新数据,遍历得重来一遍。
  • 内存占用高 千万别往里塞上万条、甚至百万级别数据。
  • 线程安全≠银弹 要是真有写多场景,还得老老实实用锁或者选用别的并发集合。

适合这样:

  • "配置黑板"类读多改少
  • 维护小容量缓存
  • 偶尔边迭代边刮胡子改几个元素

收个尾巴

说白了,CopyOnWriteArrayList 就是个谈恋爱怕闹分手的"安全派": 你要改,我就自个儿带球跑路,剩下的你们慢慢看前任。 用得好,项目稳如老狗;用错场景,队友只会拿你祭天。

所以,下回再遇到多线程需要安全集合的场景,还得盘一盘,别再头铁乱撸 CopyOnWriteArrayList 啦!

------聊着聊着,咖啡快凉了,晚安,我的并发朋友们。

相关推荐
呆呆敲代码的小Y14 分钟前
【实战精选面试题】C# 面试题详细解答,按难易程度排序
android·java·游戏·c#·游戏开发·unity面试题·c#面试题
水无痕simon29 分钟前
3、工程重构
java·spring cloud·重构
阿里云基础软件39 分钟前
Agent 任务提速 10.71%,内存占用降低 21.60%|Alibaba Cloud Linux 4 重大发布
java·linux·人工智能·操作系统·agent
Wang's Blog1 小时前
Java 项目实战: 交友项目 - 项目:需求分析与滑动数据设计
java·开发语言·交友
前端 贾公子2 小时前
第 5 章:Codex 从可运行程序到可交付工具
java·前端·数据库
CoderYanger2 小时前
Java EE 进阶:5. Spring IoC&DI(第三弹):Spring DI
java·开发语言·spring boot·spring·面试·java-ee·mvc
一条泥憨鱼2 小时前
【Kafka】零基础学习教程
java·分布式·学习·kafka
Wang's Blog2 小时前
Java 项目实战:交友项目 - 即时通信总结:全链路复盘、可复用清单与自检
java·python·交友
文丑颜不良啊2 小时前
LeetCode1501~1520题目解析
java·leetcode
长不大的杨瑞杰3 小时前
OpenCode v2 LSP 实战:内置语言服务器、自定义配置与诊断闭环
java·人工智能·typescript·lsp·opencode