原文来自于:zha-ge.cn/java/21
HashMap 与 ConcurrentHashMap 有什么区别?通俗易懂版
引子:一次线上血案
那天下午,阳光正好,我正在悠闲地喝着咖啡,突然钉钉疯狂响起------线上系统崩了!用户疯狂投诉说页面卡死,数据丢失。
打开监控一看,CPU 使用率飙到 100%,线程全部卡在一个看似无害的 HashMap 操作上。我心里咯噔一下:完了,又是并发问题!
这让我想起了一个经典的比喻:HashMap 就像一个普通的记事本,一个人用没问题,但如果多个人同时在上面写字,那就乱套了。
探索:HashMap 的"单线程世界"
HashMap 在单线程环境下表现完美,就像一个勤劳的管家:
java
// HashMap 的基本操作,单线程下很安全
Map<String, String> userCache = new HashMap<>();
userCache.put("user123", "张三");
String userName = userCache.get("user123");
// 一切都很美好...直到并发来了
但在多线程环境下,HashMap 就像一个没有交通规则的十字路口------车辆(线程)从四面八方涌来,撞车(数据竞争)是必然的。
我开始翻阅源码,发现 HashMap 的 resize()
方法在并发时会形成环形链表,导致 CPU 100% 的死循环。这就是著名的"HashMap 死循环"问题。
转折:踩坑瞬间
当时我天真地想:"既然有并发问题,那我加个 synchronized
不就行了?"
java
// 我的第一次"聪明"尝试
Map<String, String> userCache = new HashMap<>();
synchronized(userCache) {
userCache.put("user456", "李四");
}
synchronized(userCache) {
String userName = userCache.get("user456");
}
结果发现性能直接跪了!就像在高速公路上设置红绿灯,所有车辆都得排队等待,吞吐量暴跌 80%。
更要命的是,如果忘记在某个地方加 synchronized
,程序依然会出问题。这种方案就像在雷区走路,一不小心就踩雷。
解决:ConcurrentHashMap 闪亮登场
这时候,ConcurrentHashMap 就像一个经验丰富的交通管制员出现了。它采用了"分段锁"的设计理念:
- HashMap:整个十字路口只有一个红绿灯,所有方向都得等
- ConcurrentHashMap:把十字路口分成多个小区域,每个区域独立管理
java
// ConcurrentHashMap:并发安全且高效
ConcurrentHashMap<String, String> userCache = new ConcurrentHashMap<>();
// 多个线程可以同时操作不同的段
userCache.put("user789", "王五"); // 线程 1
String userName = userCache.get("user123"); // 线程 2 同时执行
// 和谐共处,性能还很棒
ConcurrentHashMap 的核心优势:
特性 | HashMap | ConcurrentHashMap |
---|---|---|
线程安全 | ❌ | ✅ |
并发性能 | N/A | 优秀 |
空值支持 | ✅ | ❌ |
迭代器 | 快速失败 | 弱一致性 |
经验启示
经过这次血泪教训,我总结了几个关键点:
什么时候用 HashMap?
- 单线程环境:性能最优,无脑选择
- 不可变数据:初始化后不再修改
- 局部变量:方法内部使用,天然线程安全
什么时候用 ConcurrentHashMap?
- 多线程环境:必选项,没得商量
- 高并发场景:读写操作频繁
- 缓存场景:多个线程共享数据
踩坑提醒
- 别想着给 HashMap 加锁:性能损失巨大,还容易出错
- 注意 null 值:ConcurrentHashMap 不允许 null 键或值
- 迭代器行为 :ConcurrentHashMap 的迭代器不会抛
ConcurrentModificationException
总结
这次经历让我深刻理解了一个道理:选择合适的工具,比优化代码更重要。
HashMap 就像跑车,在赛道上飞驰;ConcurrentHashMap 就像越野车,在复杂地形中稳定前行。关键是要在合适的场景选择合适的工具。
现在每当有新人问我这个问题,我都会告诉他们:单线程用 HashMap,多线程用 ConcurrentHashMap,简单粗暴,不会错!
记住,程序员的智慧不在于写出多复杂的代码,而在于选择最合适的解决方案。毕竟,生产环境的稳定性,比任何炫技都重要。