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

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

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

有那么一天,咖啡喝多了,脑袋嗡嗡响,领导突然"温柔"地甩过来一坨需求:"你这List用的安全吗?多线程下会不会爆炸?" 我一口激浪差点喷屏幕,线程安全集合,这不是老生常谈嘛。可是等我翻代码,才发现自己其实只认识 Collections.synchronizedList 和 Vector,其他的都进垃圾回收站了。哎,这锅不能背,得扒一扒 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 系列,起码不会坑队友。 写代码就是这样嘛,边挨锤边成长,踩坑万岁!

相关推荐
wno70415 小时前
Springboot国际化信息(i18n)解析
java·spring boot·后端
eleven_4u15 小时前
QPS如何计算,如何部署架构
java·linux·运维·jvm·中间件
牧瀬クリスだ16 小时前
Redis Hash实战:高效存储对象与购物车
java·数据库·redis·算法·哈希算法
文丑颜不良啊16 小时前
LeetCode1141~1160题目解析
java·leetcode
木井巳16 小时前
【动态规划: 路径问题】下降路径最小和
java·算法·leetcode·动态规划·推荐算法
秋饼16 小时前
MySQL 分库分表完全指南:ShardingSphere-JDBC 实战、分片键选型、场景边界、20 个生产坑与 30 道面试点
java·mysql·面试·shardingsphere·分库分表·后端架构
郭小李16 小时前
spring 的 @CookieValue 注解 用法
java·后端·spring
天远Date Lab16 小时前
零信任架构实战:基于天远企业股权变更构建自动化招投标供应商股东穿透审查网关
java·人工智能·架构·自动化
weixin_3993806917 小时前
TongWeb7.0.4.9M11如何接入到idea(by lqw)
java·ide·intellij-idea
paopaokaka_luck17 小时前
社区服务平台(加权协同过滤推荐、Jieba中文词频分析、WebSocket实时聊天、求助处理闭环、 活动积分闭环、ECharts多维分析)
java·前端·spring boot·mysql·echarts·mybatis