0

0

Java并发编程中ConcurrentHashMap怎么实现_原理与优势解析

P粉602998670

P粉602998670

发布时间:2026-01-26 09:56:03

|

480人浏览过

|

来源于php中文网

原创

ConcurrentHashMap 的分段锁被废弃是因为 Java 8 彻底重写为基于 Node 数组 + synchronized 单桶锁、CAS 和 volatile,解决了 Segment 锁粒度粗、内存高、扩容复杂等问题。

java并发编程中concurrenthashmap怎么实现_原理与优势解析

ConcurrentHashMap 的分段锁为什么被废弃了?

Java 8 及以后版本中,ConcurrentHashMap 已完全移除 Segment 分段锁机制,不是“优化”,而是彻底重写。旧版(Java 7)用 Segment 数组模拟多把锁,但存在锁粒度粗、内存占用高、扩容复杂等问题。JDK 8 改为基于 Node 数组 + synchronized 锁单个桶(bin),配合 volatile 读和 CAS 操作,既降低竞争又避免锁膨胀。

  • Java 7 的 Segment 实际是 ReentrantLock 子类,每个 Segment 管理多个桶,锁粒度仍偏大
  • Java 8 中,只有在链表转红黑树、插入冲突、扩容等关键路径才加 synchronized,且只锁当前 Node 所在桶头节点
  • size() 不再依赖全局锁或 Segment 计数,改用 baseCount + CounterCell[] 的 CAS 分段计数,但结果是最终一致而非强实时

get() 方法真的完全无锁吗?

是的,get() 在绝大多数情况下不加锁,但前提是数据未处于结构变更中(如正在扩容、树化)。它依赖 volatile 语义读取 Node.valNode.next 字段,保证看到最新写入值;而数组本身用 Unsafe.getObjectVolatile() 读取,确保不会发生指令重排导致读到未初始化的桶。

  • 如果遇到正在迁移的桶(ForwardingNode),get() 会直接去新表查找,不阻塞也不重试
  • 若当前桶是红黑树节点(TreeBin),则调用其 find() 方法——该方法内部也无需加锁,因为树结构在读期间不会被修改(写操作会先锁住 TreeBin 根节点)
  • 注意:get() 不保证看到其他线程刚 put() 但尚未完成 CAS 写入 next 字段的中间状态,这是 JMM 允许的正常现象

put() 过程中如何避免死循环?

Java 8 的 ConcurrentHashMap.put() 在链表遍历时使用 == 判断节点是否为自身(即 e == e),作为链表未损坏的快速校验。一旦发现 next 字段指向自己(e.next == e),说明链表已被其他线程标记为正在迁移(变成 ForwardingNode),立即跳出并协助扩容,而不是继续遍历造成无限循环。

for (Node e = f;;) {
    if (e == null) { /* 插入 */ break; }
    else if (e.hash == hash && key.equals(e.key)) { /* 覆盖 */ break; }
    else if (e instanceof TreeBin) { /* 树操作 */ break; }
    else if (e == e.next) // 关键防护:检测自引用,避免死循环
        break;
    e = e.next;
}
  • 这个 e == e.next 判断不是“修复”手段,而是早期退出信号,后续逻辑会转向 helpTransfer()
  • 红黑树操作由 TreeBin 统一管理,其 waiter 字段和 lockRoot() 机制防止并发写导致结构错乱
  • 所有 CAS 更新(如 tab[i]node.next)都使用 Unsafe 的有序/延迟写入,避免因编译器或 CPU 重排引发可见性问题

为什么不能用 ConcurrentHashMap 替代 synchronized 块?

ConcurrentHashMap 是线程安全的容器,不是通用同步工具。它不提供跨操作的原子性保障,比如“检查是否存在再 put”(if (!map.containsKey(k)) map.put(k, v))仍是竞态的,必须用 computeIfAbsent() 或显式加锁。

极简智能王
极简智能王

极简智能- 智能聊天AI绘画,还可以创作、编写、翻译、写代码等多种功能,满足用户生活和工作的多方面需求

下载

立即学习Java免费学习笔记(深入)”;

  • computeIfAbsent() 是唯一推荐的“读-改-写”原子操作,其内部对 key 对应桶加锁,且只在 key 不存在时执行 mappingFunction
  • replace(K, V, V)remove(K, V) 支持条件更新,依赖 CAS 比较旧值,但仅限单个 entry
  • 想实现类似 synchronized(map) { ... } 的全局互斥?别这么做——它会严重退化性能,且违背 ConcurrentHashMap 的设计初衷
  • 真正需要强一致性+复合逻辑时,应该考虑 StampedLock 或外部协调机制,而不是强行塞进 map 操作里

实际用的时候,最常被忽略的是:它的弱一致性语义(尤其是迭代器)和 size() 的估算性质。如果你在高并发下靠 size() == 0 判断是否清空完毕,或者用 keySet().iterator() 遍历时假设能看见所有已提交的写入,就很容易出错。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

867

2023.06.15

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

745

2023.07.05

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

741

2023.07.31

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

398

2023.08.01

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

420

2023.08.02

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

447

2023.08.02

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

431

2023.08.02

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

16948

2023.08.03

拼多多赚钱的5种方法 拼多多赚钱的5种方法
拼多多赚钱的5种方法 拼多多赚钱的5种方法

在拼多多上赚钱主要可以通过无货源模式一件代发、精细化运营特色店铺、参与官方高流量活动、利用拼团机制社交裂变,以及成为多多进宝推广员这5种方法实现。核心策略在于通过低成本、高效率的供应链管理与营销,利用平台社交电商红利实现盈利。

14

2026.01.26

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 2.9万人学习

C# 教程
C# 教程

共94课时 | 7.6万人学习

Java 教程
Java 教程

共578课时 | 51.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号