讲师中心 微信公众号
AI工具推荐 视频效率加速

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

云明同学_5726

云明同学_5726

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

|

520人浏览过

|

来源于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.val 和 Node.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),立即跳出并协助扩容,而不是继续遍历造成无限循环。

Blender Geometry Nodes Script Generator
Blender Geometry Nodes Script Generator

生成Blender Python (bpy)脚本,该脚本使用node_groups API和GeometryNodeTree接口程序化地创建几何节点修改器树,用于参数化3D资产生成。

下载
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() 或显式加锁。

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

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

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

相关文章

编程速学教程(入门课程)
编程速学教程(入门课程)

编程怎么学习?编程怎么入门?编程在哪学?编程怎么学才快?不用担心,这里为大家提供了编程速学教程(入门课程),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

PixTV
PixTV Hot

PixTV是一款面向AIGC内容创作的AI视频生成工具。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

创客贴AI

创客贴AI是一款AI图像与设计工具,AI辅助的智能在线设计工具。

花生AI
花生AI Hot

一款AI视频创作工具,主要用于B站推出的AI视频创作工具,适合需要提升相关任务效率的用户。

PixPix
PixPix Hot

PixPix是一款面向电商视觉生产的AI商品图生成工具。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

相关专题

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

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

814

2025.10.23

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

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

4638

2023.08.10

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

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

690

2025.09.05

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

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

343

2025.11.16

golang map原理
golang map原理

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

553

2025.11.17

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

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

303

2025.11.27

DBeaver怎么导入数据
DBeaver怎么导入数据

DBeaver数据导入专题,整理Excel、CSV、SQL、TXT等常见文件的数据导入方法,涵盖目标数据库选择、数据表创建、字段映射、数据类型设置及导入参数配置等操作,帮助用户将本地文件中的数据写入数据库,并了解批量导入、重复数据处理和导入失败等常见问题的解决方法。

0

2026.11.05

DBeaver安全防护教程大全
DBeaver安全防护教程大全

DBeaver安全防护专题,围绕数据库连接安全、账号密码保护和访问权限管理展开,整理SSL/TLS加密连接、SSH隧道、数据库凭据保存及证书验证等配置方法,同时介绍敏感信息保护、远程连接风险和高权限账号使用等注意事项,帮助用户提高数据库日常管理的安全性。

0

2026.11.05

DBeaver连接创建与配置教程
DBeaver连接创建与配置教程

本专题聚焦DBeaver数据库连接配置与管理,覆盖从新建连接、选择数据库类型到填写连接参数和验证连接的完整流程。针对MySQL、PostgreSQL、SQL Server等常见数据库,整理相应的连接设置方法,并提供驱动缺失、认证失败和连接异常等问题的排查方向。

0

2026.11.04

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn