一、ConcurrentHashMap 核心作用ConcurrentHashMap是 Java 并发包java.util.concurrent中提供的线程安全的哈希表实现它的核心作用是在多线程环境下支持高并发的读写操作避免了HashMap线程不安全导致的问题如死循环、数据丢失。相比传统的Hashtable全表加锁或Collections.synchronizedMap()包装后的 HashMap也是全表锁ConcurrentHashMap采用分段锁 / 精细化锁机制大幅提升了并发性能。支持并发度默认 16允许多个线程同时操作不同的分段区域读写之间尽可能不阻塞。二、ConcurrentHashMap 底层实现按 JDK 版本划分ConcurrentHashMap的底层实现在 JDK 1.7 和 JDK 1.8 有重大变化其中 JDK 1.8 是目前主流使用的版本我会重点讲解。1. JDK 1.7 实现分段锁Segment HashEntry核心结构Segment继承自ReentrantLock是一个可重入锁相当于 “锁桶”。一个ConcurrentHashMap包含多个Segment默认 16 个每个Segment对应一个数组数组元素是HashEntry链表。HashEntry存储键值对的节点结构和HashMap的Entry类似但value和next用volatile修饰保证可见性。核心原理哈希计算key 先经过一次哈希得到Segment的索引再对Segment内的数组做二次哈希定位到具体的HashEntry节点。加锁粒度只对操作的Segment加锁其他Segment不受影响。例如线程 A 操作 Segment1线程 B 操作 Segment2两者可以并行执行只有操作同一个 Segment 的线程才会互斥。读写规则写操作put/remove获取对应Segment的锁完成操作后释放锁。读操作get无需加锁通过volatile保证节点值的可见性。2. JDK 1.8 实现CAS(Compare-And-Swap比较并交换) synchronized 红黑树废弃 SegmentJDK 1.8 抛弃了分段锁借鉴了HashMap的结构数组 链表 红黑树并通过更精细化的锁机制提升并发性能。核心结构Node 数组底层是NodeK,V类型的数组Node的value和next同样用volatile修饰。TreeNode当链表长度超过 8且数组长度≥64 时链表转为红黑树和 HashMap 逻辑一致提升查询效率。ForwardingNode扩容时的特殊节点标记当前桶正在扩容引导读操作到新数组写操作协助扩容。核心原理哈希计算和 HashMap 一致扰动函数 取模直接定位到数组的桶bucket。加锁粒度从 “Segment 级” 缩小到 “桶级”—— 只对操作的数组桶单个 Node 节点加锁并发度更高。核心操作逻辑put 操作计算 key 的哈希值定位到数组桶。如果桶为空通过CAS无锁方式插入节点避免加锁开销。如果桶不为空检查桶的首节点若首节点是ForwardingNode扩容中协助扩容后再插入。否则用synchronized锁定首节点遍历链表 / 红黑树完成插入 / 覆盖。插入后检查链表长度超过阈值则转为红黑树。get 操作无需加锁通过volatile保证节点的可见性步骤定位到数组桶检查首节点是否匹配 key匹配则返回 value。不匹配则遍历链表 / 红黑树找到则返回 value否则返回 null。扩容操作采用 “多线程分段扩容”—— 每个线程负责一部分桶的迁移通过ForwardingNode标记扩容状态避免重复扩容。size 操作无需遍历全表通过累加baseCount基础计数和counterCells分段计数实现避免全表加锁。线程安全保障写操作CAS无锁场景 synchronized锁桶保证原子性。读操作volatile 保证可见性无需加锁弱一致性允许读到旧值但不会读到脏数据。扩容多线程协作避免单线程扩容的性能瓶颈。三、ConcurrentHashMap 与 HashMap 的核心区别特性HashMapConcurrentHashMap线程安全非线程安全线程安全锁机制无锁JDK1.7分段锁JDK1.8CASsynchronized空值支持允许 key/value 为 nullkey 仅 1 个不允许 key/value 为 null避免并发场景下判空歧义迭代器特性快速失败fail-fast迭代中修改会抛ConcurrentModificationException弱一致性fail-safe迭代器是快照不会抛异常可能读到旧值扩容机制单线程扩容多线程分段扩容JDK1.8性能多线程高并发下可能死循环 / 数据错乱性能差高并发下性能优异锁粒度极小使用场景单线程 / 低并发读多写少高并发多线程环境补充说明为什么 ConcurrentHashMap 不支持 nullHashMap 中get(key)返回 null 时无法区分 “key 不存在” 还是 “key 对应 value 是 null”而 ConcurrentHashMap 用于多线程场景若允许 null会增加并发下的歧义处理成本因此直接禁止。弱一致性的体现迭代 ConcurrentHashMap 时迭代器会先获取当前数组的快照后续数组的修改不会反映到迭代器中因此不会抛ConcurrentModificationException但可能读到迭代前的旧数据。总结ConcurrentHashMap的核心价值是多线程安全 高并发性能相比传统的线程安全哈希表Hashtable它通过精细化锁分段锁 / JDK1.8 桶锁和 CAS 机制大幅提升并发效率。JDK 1.8 是 ConcurrentHashMap 的主流实现抛弃分段锁采用 “CAS synchronized 红黑树”锁粒度缩小到单个桶并发性能更优。与 HashMap 的核心区别在于线程安全、空值支持、迭代器特性前者适用于高并发场景后者适用于单线程 / 低并发场景。