
HashMap 和 ConcurrentHashMap 到底差在哪
2026-07-02
✨ 心情:💻
# Java
# 面试
面试必考题,但你真的理解透彻了吗?
先说 HashMap。JDK 1.8 之后是数组+链表+红黑树结构,hash 冲突时链表长度 >= 8 且数组长度 >= 64 时转红黑树,查得快。但它不是线程安全的——并发 put 时可能导致链表成环(死循环),或者数据覆盖。
ConcurrentHashMap 就不一样了:
- 1.7 之前用分段锁(Segment),默认 16 段,每段独立加锁
- 1.8 之后用 CAS + synchronized 锁住链表头节点,粒度更细
- 读操作不加锁,因为 Node 的 val 和 next 都是 volatile 的
- size() 不再是精确值,而是估算(baseCount + counterCells)
还有一个很多人忽略的点:ConcurrentHashMap 的 key 和 value 都不能为 null。HashMap 可以。原因也很简单——在多线程环境下,get(key) 返回 null 到底是 key 不存在还是 value 就是 null?没法区分。
记住一句话:能用 ConcurrentHashMap 就别自己加锁。