原来 Java 里线程安全集合有这么多种

原文来自于:zha-ge.cn/java/77

原来 Java 里线程安全集合有这么多种

有那么一天,咖啡喝多了,脑袋嗡嗡响,领导突然"温柔"地甩过来一坨需求:"你这List用的安全吗?多线程下会不会爆炸?" 我一口激浪差点喷屏幕,线程安全集合,这不是老生常谈嘛。可是等我翻代码,才发现自己其实只认识 Collections.synchronizedListVector,其他的都进垃圾回收站了。哎,这锅不能背,得扒一扒 Java 里的线程安全集合到底有几路豪杰。


初见江湖:这些名字我都见过?

Java 集合家族其实超级大,线程安全的那些,堪比武林门派,各有绝技。

  • Vector, Hashtable 这些上古遗迹,虽然老,但能保命。
  • Collections.synchronizedXXX 工厂方法,给老集合套个线程安全"特效皮肤"。
  • ConcurrentHashMap, CopyOnWriteArrayList 等并发大佬,JDK5后出道,秒杀前辈。

我还腾了个小表格,请叫我表哥:

集合名 线程安全性 优势 劣势
Vector 安全 祖传防爆,简单易懂 性能糟糕
Collections.synchronizedList 安全 易于转换,老代码福音 性能一般,颗粒粗
ConcurrentHashMap 超级安全 读多写少场景无敌,细粒度锁 写多可能瓶颈
CopyOnWriteArrayList 读安全 读写分离,读场景快 写操作开销大

砸场子的瞬间

我一开始跑路 Collections.synchronizedList,写了个多线程测试自信满满,结果直接春哥再临。问题出在哪?

java 复制代码
List<String> syncList = Collections.synchronizedList(new ArrayList<>());
for (int i = 0; i < 1000; i++) {
    new Thread(() -> {
        syncList.add(Thread.currentThread().getName());
    }).start();
}
// 等等再遍历
for (String name : syncList) {
    System.out.println(name);
}

别问我为啥会ConcurrentModificationException,问就是for-each遍历没加锁。线程安全这个事儿,还得自己上心啊!上了锁,世界才安静:

java 复制代码
synchronized (syncList) {
    for (String name : syncList) {
        System.out.println(name);
    }
}

但这不优雅啊朋友,终于理解为啥 CopyOnWriteArrayList 会受宠。


踩坑瞬间

  • 以为加了 Collections.synchronizedList 就万事大吉,结果遍历都没锁上,直接爆炸。
  • Vector 还能用吗?能,但写多别碰它,性能跑不过 Concurrent 家族。
  • CopyOnWriteArrayList 很香,但写操作多会让你怀疑人生,因为每次写都要拷贝,内存都差点不够用了。
  • ConcurrentHashMap 的 Key/Value 不能随便为 null,不是所有 Map 都惯着你。

经验启示

  • 不是加了"线程安全"标签就能无脑用,遍历时记得手动加锁,尤其是同步包装类。
  • 读多写少就用 CopyOnWriteArrayList/Set/Map,写多还是 Concurrent 家族靠谱。
  • Vector、Hashtable 真的是爷青结,只适合和遗留系统"深情对望"。
  • 别的门派不懂的,别忘了 JavaDoc 黄金屋,多看看说明书,比我瞎踩坑省时多了。

最后,我现在面对线程安全集合都学会了一个骚操作:先问,啥场景?多读还是多写?要啥功能? 真不确定,用 Concurrent 系列,起码不会坑队友。 写代码就是这样嘛,边挨锤边成长,踩坑万岁!

相关推荐
卡布奇诺-海晨7 小时前
2025版本的idea解决Git冲突
java·git·intellij-idea
Flash Dog7 小时前
【MyBatis】——执行过程
java·mybatis
Li_7695327 小时前
2025.2.X 版本 IDEA maven 打包乱码问题的解决
java·maven·intellij-idea
DKPT8 小时前
JVM栈溢出和堆溢出哪个先满?
java·开发语言·jvm·笔记·学习
m0_475064508 小时前
jvm双亲委派的含义
java·jvm
毕设源码-朱学姐13 小时前
【开题答辩全过程】以 爱心捐赠网站为例,包含答辩的问题和答案
java·eclipse
尘觉14 小时前
中秋节与 Spring Boot 的思考:一场开箱即用的团圆盛宴
java·spring boot·后端
Le1Yu15 小时前
2025-10-7学习笔记
java·笔记·学习
popoxf15 小时前
spring容器启动流程(反射视角)
java·后端·spring
AAA修煤气灶刘哥16 小时前
监控摄像头?不,我们管这个叫优雅的埋点艺术!
java·后端·spring cloud