ConcurrentHashMap通过分段锁(JDK7)和CAS+synchronized桶级锁(JDK8)实现高并发安全,支持原子操作与红黑树优化,显著优于Vector和Hashtable的全表锁机制。

Vector:粗粒度锁的线程安全起点
Vector 是 Java 最早提供的线程安全 List 实现,底层和 ArrayList 一样基于动态数组,区别仅在于所有公有方法(add、remove、get、size 等)都加了 synchronized 关键字。这相当于对整个 Vector 对象加了一把独占锁——任意线程调用任一方法,都会阻塞其他所有线程的访问。
这种设计保证了绝对的线程安全性,但代价明显:
- 读写操作互斥,即使只是并发读取,也无法并行
- 扩容时需锁住整个结构,高并发下吞吐量急剧下降
- 迭代器不支持“边遍历边修改”,仍可能抛出 ConcurrentModificationException
Hashtable:Map 领域的同步容器对标
与 Vector 类似,Hashtable 是 HashMap 的线程安全版本,所有方法也使用 synchronized 修饰。它锁的是整个哈希表实例,导致读写串行化,尤其在读多写少场景中性能浪费严重。
它比 HashMap 多出的限制还包括:
- 不允许 null 键或 null 值(HashMap 允许一个 null 键和多个 null 值)
- 没有提供原子性复合操作(如 putIfAbsent)
- 扩容时全表 rehash,锁持有时间长
ConcurrentHashMap:分段锁到无锁演进的里程碑
ConcurrentHashMap 是为真正高并发场景而生的设计,其核心思路是“降低锁粒度”乃至“避免锁”。演进分为两个关键阶段:
- JDK 7:采用 Segment 分段锁机制,默认 16 个 Segment,每个 Segment 是一个独立的 HashEntry 数组 + ReentrantLock。不同 Segment 之间可并行读写,大幅减少竞争
- JDK 8:彻底移除 Segment,改用 CAS + synchronized 锁单个 Node 桶。数组元素(Node)的 val 和 next 字段为 volatile,保障可见性;put 操作只锁定目标桶头节点;链表长度 ≥8 且数组容量 ≥64 时转为红黑树,优化查找性能
此外,ConcurrentHashMap 还支持原子操作:
- putIfAbsent:仅当 key 不存在时插入
- replace(key, oldValue, newValue):带旧值校验的替换
- computeIfAbsent / computeIfPresent:延迟计算,避免重复构造
演进背后的本质逻辑
从 Vector 到 ConcurrentHashMap,不是简单替换,而是对“并发安全”与“性能开销”权衡的持续优化:
- 锁范围:对象级锁 → 分段锁 → 桶级锁 → CAS 无锁读 + 局部锁写
- 数据结构:纯数组/链表 → Segment+HashEntry → Node 数组+链表/红黑树
- 语义能力:基础增删改查 → 原子复合操作 → 支持函数式更新与懒加载
- 适用场景:低并发、强一致性要求 → 中高并发、读多写少 → 超高并发、低延迟敏感
今天的 ConcurrentHashMap 已成为高并发服务中 Map 类型事实上的标准选择,而 Vector 和 Hashtable 几乎只存在于遗留系统或教学示例中。

















