0

0

Java中如何通过ConcurrentHashMap实现分段锁

P粉602998670

P粉602998670

发布时间:2025-11-01 08:52:02

|

180人浏览过

|

来源于php中文网

原创

ConcurrentHashMap在Java 8中采用CAS+synchronized取代分段锁,通过桶级加锁提升并发性能。

java中如何通过concurrenthashmap实现分段锁

ConcurrentHashMap 在 Java 中并不是通过“分段锁”来实现线程安全的,尤其是在 Java 8 及以后版本中。你提到的“分段锁”其实是 ConcurrentHashMap 在 Java 7 中的实现机制,而在 Java 8 中已经被更高效的 CAS + synchronized 方式取代。下面分别说明这两个版本的实现思路。

Java 7:基于分段锁(Segment)

在 Java 7 中,ConcurrentHashMap 的核心思想是将整个哈希表分成多个段(Segment),每个段相当于一个独立的 HashTable,拥有自己的锁。这样,在多线程环境下,不同线程可以操作不同的 Segment,从而减少锁竞争,提高并发性能。

关键点:
  • ConcurrentHashMap 内部包含一个 Segment 数组,每个 Segment 继承自 ReentrantLock。
  • 默认有 16 个 Segment,意味着最多可以同时支持 16 个线程并发写操作(前提是它们操作不同的 Segment)。
  • 每次 put 操作时,先根据 key 的 hash 值定位到某个 Segment,然后对该 Segment 加锁。
  • 读操作(get)不需要加锁,因为内部值是 volatile 的,保证可见性。

这种方式实现了“分段锁”,即锁的粒度从整个 Map 降低到了 Segment 级别,提高了并发度。

Java 8:CAS + synchronized 优化

Java 8 彻底重构了 ConcurrentHashMap 的实现。不再使用 Segment,而是采用更细粒度的锁机制:使用 Node 数组 + 链表/红黑树,并结合 CAS 操作和 synchronized 关键字对链表头或树节点加锁。

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

关键改进:
  • 底层结构类似 HashMap,使用 Node 数组存储数据。
  • 插入时使用 CAS 操作进行无锁化尝试,失败后再使用 synchronized 锁住当前桶(bucket)的头节点。
  • 当链表长度超过阈值(默认 8),且数组长度大于 64 时,链表转为红黑树,提升查找效率。
  • volatile 保证变量的可见性,如数组引用和节点值。

这种设计比 Segment 更加灵活,锁的粒度进一步缩小到具体的桶(数组元素),并发性能更好,内存开销也更低。

DreamStudio
DreamStudio

SD兄弟产品!AI 图像生成器

下载

如何理解“分段锁”的遗留概念?

虽然 Java 8 后没有显式的 Segment 分段锁,但其并发控制的本质仍然是“分段”思想的延续——即把锁的范围限制在数组的某个桶上,而不是整个 Map。你可以理解为:现在的“段”就是数组中的每一个 bucket。

示例代码(Java 8+):

当你调用 put 方法时:

  • 计算 key 的 hash 值,确定数组下标。
  • 如果该位置为空,使用 CAS 插入新节点。
  • 如果不为空,synchronized 锁住该位置的头节点,再进行插入或更新。

不同线程操作不同 bucket 时,互不阻塞,实现了高并发写入。

基本上就这些。ConcurrentHashMap 的演进体现了从“分段锁”到“更细粒度锁 + 无锁化操作”的趋势,核心目标始终是减少锁竞争、提升并发性能。

热门AI工具

更多
DeepSeek
DeepSeek

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

豆包大模型
豆包大模型

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

WorkBuddy
WorkBuddy

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

腾讯元宝
腾讯元宝

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

文心一言
文心一言

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

讯飞写作
讯飞写作

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

即梦AI
即梦AI

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

ChatGPT
ChatGPT

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

相关专题

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

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

76

2025.10.23

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

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

766

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

377

2025.12.24

java多线程相关教程合集
java多线程相关教程合集

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

33

2026.01.21

C++多线程相关合集
C++多线程相关合集

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

31

2026.01.21

C# 多线程与异步编程
C# 多线程与异步编程

本专题深入讲解 C# 中多线程与异步编程的核心概念与实战技巧,包括线程池管理、Task 类的使用、async/await 异步编程模式、并发控制与线程同步、死锁与竞态条件的解决方案。通过实际项目,帮助开发者掌握 如何在 C# 中构建高并发、低延迟的异步系统,提升应用性能和响应速度。

104

2026.02.06

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

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

77

2025.09.05

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

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

40

2025.11.16

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

49

2026.03.13

热门下载

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

精品课程

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

共23课时 | 4.4万人学习

C# 教程
C# 教程

共94课时 | 11.4万人学习

Java 教程
Java 教程

共578课时 | 82.3万人学习

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

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