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<K,V> 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() 或显式加锁。

Chromox
Chromox

Chromox是一款领先的AI在线生成平台,专为喜欢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

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

豆包大模型
豆包大模型

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

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

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

文心一言
文心一言

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

讯飞写作
讯飞写作

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

即梦AI
即梦AI

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

ChatGPT
ChatGPT

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

相关专题

更多
if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

847

2023.08.22

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

847

2023.08.22

c++中volatile关键字的作用
c++中volatile关键字的作用

本专题整合了c++中volatile关键字的相关内容,阅读专题下面的文章了解更多详细内容。

75

2025.10.23

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

765

2023.08.10

golang map内存释放
golang map内存释放

本专题整合了golang map内存相关教程,阅读专题下面的文章了解更多相关内容。

77

2025.09.05

golang map相关教程
golang map相关教程

本专题整合了golang map相关教程,阅读专题下面的文章了解更多详细内容。

40

2025.11.16

golang map原理
golang map原理

本专题整合了golang map相关内容,阅读专题下面的文章了解更多详细内容。

67

2025.11.17

java判断map相关教程
java判断map相关教程

本专题整合了java判断map相关教程,阅读专题下面的文章了解更多详细内容。

47

2025.11.27

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

76

2026.03.11

热门下载

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

精品课程

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

共23课时 | 4.4万人学习

C# 教程
C# 教程

共94课时 | 11.2万人学习

Java 教程
Java 教程

共578课时 | 81.2万人学习

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

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