当前位置: 首页 > news >正文

一文搞懂ConcurrentHashMap底层原理

当然可以!下面是一篇深入浅出、结构清晰的《一文搞懂 ConcurrentHashMap 底层原理》,基于 JDK 8+,帮助你彻底掌握其高并发设计精髓。

一文搞懂 ConcurrentHashMap 底层原理(JDK 8+)

一、为什么需要 ConcurrentHashMap?

HashMap 在多线程环境下存在严重问题(如死循环、数据丢失),而 Hashtable 虽线程安全,但全局加锁导致性能极差。
ConcurrentHashMap(简称 CHM) 应运而生:高并发 + 高性能 + 线程安全。

✅ 核心目标:在保证线程安全的前提下,尽可能减少锁的粒度,提升并发吞吐量。

二、JDK 7 vs JDK 8 的底层结构演进
版本 底层结构 锁机制
JDK 7 分段锁(Segment + HashEntry)数组 + 链表,Segment 继承 ReentrantLock 每个 Segment 独立加锁(最多 16 个并发)

JDK 8+ 数组 + 链表/红黑树(与 HashMap 类似) CAS + synchronized(锁单个桶)

🚀 JDK 8 是一次重大重构:取消 Segment,直接对每个桶(Node)加锁,锁粒度更细,并发度更高!

三、JDK 8 中的核心数据结构

transient volatile Node[] table;

  • Node:基本节点,包含 key、value、hash、next
  • TreeNode:红黑树节点(继承自 Node)
  • ForwardingNode:扩容时使用的特殊节点(hash = -1),指向新 table
  • TreeBin:红黑树的代理节点(负责树操作的同步)

🔑 关键点:只在必要时加锁,且锁的是桶的头节点(synchronized (f))

四、核心机制详解

  1. 初始化(initTable)
  • 懒加载:第一次 put 时才初始化 table
  • 使用 CAS + 自旋 设置 sizeCtl(控制字段):
    if (U.compareAndSwapInt(this, SIZECTL, sc, -1)) {
    // 初始化 table
    }
  1. put 操作流程(线程安全插入)

public V put(K key, V value) {
return putVal(key, value, false);
}

步骤如下:

  1. 计算 hash 值(与 HashMap 相同)
    int hash = spread(key.hashCode());

    spread() 保证 hash 高位不为负(避免与特殊 hash 冲突)

  2. 如果 table 未初始化 → 调用 initTable()

  3. 定位桶位置:(n - 1) & hash

  4. 根据桶状态处理:

    • 情况①:桶为空
      → 使用 CAS 直接插入新节点(无锁!)
    • 情况②:正在扩容(桶为 ForwardingNode)
      → 当前线程协助扩容(helpTransfer)
    • 情况③:桶非空(链表或红黑树)
      → synchronized 锁住该桶的头节点,遍历插入或更新
  5. 插入后检查是否需要树化(同 HashMap:链表 ≥8 且 table.length ≥64)

  6. 检查是否需要扩容(size > threshold)

✅ 优势:90% 的写操作无需加锁(CAS 成功即返回),极大提升并发性能。

  1. 扩容机制(transfer)
  • 支持多线程协同扩容!这是 CHM 最精妙的设计之一。
  • 扩容时,原 table 中的每个桶会被多个线程瓜分处理(通过 stride 分配区间)
  • 桶被处理后,替换为 ForwardingNode(hash = -1),其他线程访问时会自动协助扩容
  • 新元素直接插入 新 table

💡 效果:扩容不再是“单线程阻塞操作”,而是并行任务,极大减少停顿时间。

  1. get 操作(完全无锁!)

public V get(Object key) {
// 1. 计算 hash
// 2. 定位桶
// 3. 遍历链表/红黑树,用 equals() 比较 key
}

  • 全程无锁!依靠:
    • volatile 修饰的 Node.val 和 Node.next
    • Happens-Before 语义保证可见性
  • 即使在扩容过程中,也能正确读取(通过 ForwardingNode 跳转到新 table)

⚡ 性能接近 HashMap!

五、关键优化总结
优化点 说明
取消 Segment 锁粒度从“段”细化到“桶”

CAS + synchronized 写操作尽量无锁,必要时只锁单个桶

多线程协助扩容 扩容不再阻塞,提升吞ut

volatile + final 保证内存可见性,get 无需加锁

懒初始化 节省内存

六、常见面试题

Q1:ConcurrentHashMap 如何保证线程安全?

  • 写操作:CAS(无竞争时) + synchronized(锁桶头节点)
  • 读操作:完全无锁,依赖 volatile 语义
  • 扩容:多线程协作,ForwardingNode 引导读写到新表

Q2:为什么用 synchronized 而不是 ReentrantLock?

  • JDK 6 后 synchronized 优化(偏向锁、轻量级锁)
  • synchronized 更轻量,且 JVM 可优化(锁消除、锁粗化)
  • 减少内存开销(ReentrantLock 需额外对象)

Q3:size() 方法如何实现?

  • 使用 CounterCell 数组 + baseCount 实现高并发计数
  • 类似 LongAdder 思想:分散热点,减少 CAS 冲突

Q4:能完全替代 Hashtable 吗?

  • ✅ 功能上可以,且性能远超
  • ❌ 但注意:CHM 不允许 null key/value(避免歧义)

七、使用建议

  • 优先使用 ConcurrentHashMap 而非 Collections.synchronizedMap(new HashMap())
  • 不要手动加锁:CHM 内部已处理好并发
  • 避免复合操作:如 “先 get 再 put” 不是原子的,需用 computeIfAbsent 等原子方法

// 原子操作示例
map.computeIfAbsent(key, k -> new Value());

总结
特性 ConcurrentHashMap (JDK 8+)
线程安全 ✅

null 支持 ❌(key/value 均不允许 null)

并发度 极高(理论上等于桶数量)

读性能 无锁,接近 HashMap

写性能 CAS + 细粒度锁,远优于 Hashtable

扩容 多线程协作,高效平滑

掌握这些,你就真正理解了 ConcurrentHashMap 的高并发设计哲学:“分而治之 + 无锁优先 + 协同合作”。

如需进一步了解 size() 实现、compute 系列方法,或与 CopyOnWriteArrayList 对比,欢迎继续提问!

http://www.jsqmd.com/news/442960/

相关文章:

  • 绍兴靠谱的搬家公司推荐,如意搬家好用不? - mypinpai
  • 服务器与网站搬家怎么操作?前端源码与数据库的备份迁移操作指南
  • 分期乐购物额度回收全攻略:避坑指南 + 正规变现渠道详解 - 团团收购物卡回收
  • 2026年云端优质语音客服机器人厂商及支持私有化部署厂商推荐 - 品牌2026
  • 深入解析:IntelliJ IDEA 教程:AR/VR 开发环境搭建完整指南 [特殊字符]
  • 2026年广州瓷像瓷片信誉厂家推荐 永鑫瓷艺性价比如何 - 工业品牌热点
  • 2026年2月实践:广东水转印工厂哪家强?亲测推荐 - 界川
  • ParamMem:用参数反射记忆增强语言代理
  • 2026 沃尔玛购物卡回收全攻略:避坑指南 + 正规渠道实操步骤 - 团团收购物卡回收
  • 2026年电弧红外碳硫仪宝藏攻略:优质厂家安利,实力性价比大起底! - 品牌推荐大师
  • 旧电脑适合的系统
  • 岩棉板性能实测,2026年新型厂商产品表现如何?岩棉板/防火涂料/一体板,岩棉板厂商厂家电话 - 品牌推荐师
  • 搓牙机在紧固件生产中的作用是什么?FES上海紧固件专业展解析
  • 2026上海紧固件专业展 6月24-26日 全球紧固件产业风向标
  • 大润发卡回收安全吗?畅回收的6重防护体系曝光! - 畅回收小程序
  • 通过畅回收处理闲置大润发卡的3大意义 - 畅回收小程序
  • 网站为什么会被黑?是哪个环节问题
  • 膜脂条:Echelon EEB-P-6002,特异性检测膜脂质谱
  • 从“会聊天”到“会交付”:用 OpenClaw + DeepSeek 做一个可落地的 AI Agent 工程化流水线(Java/Go/Python)
  • 盘点2026年青岛性价比高的LED显示屏,选哪家好 - myqiye
  • 推荐的电热膜供应商,价格大概多少钱,费用合理吗? - 工业品网
  • 探讨郑州靠谱的个性化家装公司全案设计,费用多少心里有数 - 工业推荐榜
  • 天津思码精密电子 | 全流程质检闭环,质量效率双提升 - 搭贝
  • 谁懂啊!闲置百联 OK 卡终于找到靠谱的回血方式了 - 团团收购物卡回收
  • 企业ICT链路规划标准化建设与全生命周期运维实践
  • 口碑与售后双优!实验室水处理设备靠谱供应商大盘点 - 品牌推荐大师
  • 封装
  • 2026年上海靠谱婚介所服务排名,喜之缘婚介口碑出众值得推荐 - mypinpai
  • KRAS靶点研究进展与治疗突破
  • 基于DSP28335的MPU6050传感器IIC通信与原始数据读取实现