深度剖析 HashMap:从 JDK 1.7 死循环到 1.8 高低位映射优化

作者:[予枫]

发布时间:2026年1月

分类:Java 后端 / 底层原理


一、 引言:哈希冲突与 HashMap 的使命

在计算机科学中,哈希表通过哈希函数将 Key 映射到数组下标,实现 $O(1)$ 的查找效率。然而,由于哈希函数输出空间有限,哈希冲突(Hash Collision)避不可免。

常见的解决冲突方法包括:

  • 链地址法(Separate Chaining):HashMap 采用的核心策略。

  • 开放定址法(Open Addressing):如线性探测、平方探测。

  • 再哈希法(Rehashing):使用多个哈希函数。

  • 建立公共溢出区

HashMap 在单线程环境下表现卓越,但在多线程这片“深水区”,它就像一个没有交通灯的十字路口,极易引发致命灾难。


二、 HashMap 的五大线程安全陷阱

多线程同时修改同一个 HashMap 实例时,会引发以下问题:

  1. 扩容死循环(JDK 1.7):最著名的 Bug,会导致 CPU 飙升至 100%。

  2. 数据丢失/覆盖(1.7 & 1.8 共有):多个线程同时put时,由于没有加锁,计算出的索引若相同,后者的值会覆盖前者。

  3. Size 计算不准size++操作非原子性,并发下会导致计数不一致。

  4. 扩容覆盖(JDK 1.8):多线程同时扩容生成多个新数组,最终只有最后一个线程的数组会被保留,其余线程插入的数据随之丢失。

  5. 快速失败(Fail-Fast):在迭代过程中若有其他线程修改结构,会立即抛出ConcurrentModificationException


三、 深度复现:JDK 1.7 的“死亡之环”

1. 源码现场

JDK 1.7 扩容的核心在于transfer方法,其罪魁祸首是头插法(Head Insertion)

void transfer(Entry[] newTable) { Entry[] src = table; int newCapacity = newTable.length; for (int j = 0; j < src.length; j++) { Entry<K,V> e = src[j]; if (e != null) { src[j] = null; do { Entry<K,V> next = e.next; // 【关键点 1】记录下一个节点 int i = indexFor(e.hash, newCapacity); e.next = newTable[i]; // 【关键点 2】头插到新表 newTable[i] = e; e = next; // 【关键点 3】移动到下一个 } while (e != null); } } }

2. 场景分析

假设原链表为A -> B -> null

  • 线程 T1执行到记录next = B后被挂起。此时 T1 视角:e = A, next = B

  • 线程 T2完成整个扩容,由于头插法,新链表变为B -> A -> null。此时 A 的next已指向null,而 B 的next指向了 A。

  • 线程 T1 恢复

    1. 处理 A:将 A 插入新表,e变为 B。

    2. 处理 B:此时由于 T2 修改了指针,B.next变成了 A。T1 记录next = A,将 B 插入 A 之前。

    3. 再次处理 A:此时e = AA.next被设为当前头节点 B。

    • 结局B.next = AA.next = B环形链表诞生

3. 后果

当后续调用get()落入此桶时,while遍历将永不停止,导致 CPU 占用率瞬间达到 100%。


四、 JDK 1.8 的救赎:高低位映射全解析

JDK 1.8 废弃了头插法,改用尾插法并引入了高低位映射(High-Low Mapping)

1. 数学基石:2 的幂次方

HashMap 容量 $n$ 始终为 $2^k$。扩容时,新容量是旧容量的 2 倍。

  • 索引计算:$Index = (n-1) \& hash$。

  • 奇妙现象:扩容后,掩码(Mask)仅在高位多出一个1。这意味着元素新索引只有两种可能:原位置原位置 + 旧容量

2. 核心算法:四指针分流

1.8 使用loHead, loTail(低位链表)和hiHead, hiTail(高位链表)进行分选:

  • 判断条件(e.hash & oldCap) == 0

  • 低位(0):留在原位置。

  • 高位(1):搬移到index + oldCap位置。

3. 进阶:红黑树的split细节

若桶内是红黑树,扩容时调用TreeNode.split()

  • 同样按高低位拆分为两个双向链表。

  • 去树化:若拆分后长度 $\le 6$,转回普通链表。

  • 树化:若长度 $> 6$,重新构建红黑树。


五、 总结与最佳实践

为什么 1.8 的设计更优?

特性1.8 高低位映射核心价值
位运算优化(hash & oldCap)极速判定,无需 rehash,性能翻倍。
尾插法保持原序彻底解决死循环问题。
树结构拆分split逻辑保证扩容后大桶依然具备 $O(\log n)$ 的检索效率。

解决方案

在多线程环境下,请务必遵守:

  1. ConcurrentHashMap(首选):采用 CAS +synchronized细粒度锁,支持多线程协同扩容,是生产环境的最佳选择。

  2. Collections.synchronizedMap:全表加锁,性能较低。


结语:

理解 HashMap 的演进不仅仅是为了面试,更是为了学习其背后精妙的位运算设计与并发处理思路。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1120306.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

半导体集成电路详解:数字IC、逻辑器件。

半导体集成电路详解&#xff1a;数字IC、逻辑器件、微处理器与模拟IC 一、 数字IC与模拟IC&#xff1a;两大核心门类 根据WSTS分类&#xff0c;半导体芯片主要分为集成电路、分立器件、传感器和光电子器件。其中&#xff0c;集成电路&#xff08;IC&#xff0c;俗称“芯片”&am…

【课程设计/毕业设计】python基于CNN机器学习的遥感图片识别沙漠湖泊和森林基于CNN深度学习的遥感图片识别沙漠湖泊和森林

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

深度解析Apache RocketMQ:从核心原理到实战应用

在分布式系统与微服务架构中&#xff0c;消息中间件扮演着“桥梁”与“缓冲”的关键角色&#xff0c;负责实现服务解耦、异步通信、流量削峰等核心诉求。Apache RocketMQ作为一款源自阿里、捐献给Apache基金会的开源消息中间件&#xff0c;凭借其金融级可靠性、丰富的功能特性及…

怎么查看Win10系统的内存(RAM)大小?

怎么查看Win10系统的内存&#xff08;RAM&#xff09;大小&#xff1f; 查看Windows 10系统内存&#xff08;RAM&#xff09;最直接的方法&#xff1a;使用系统自带的“设置”或“任务管理器”。查看方法核心操作步骤要查看的关键信息 (示例)✅设置查看—— 最直接 (推荐)1. 打…

一个http请求的过程

总体可以分为浏览器解析、网关接收和转发、后端服务处理请求三个步骤。 浏览器的解析 首先会进行协议的判断&#xff0c;如果是https则需要增加身份认证和获取密钥的过程。接着通过DNS进行域名到ip地址和端口号的转换&#xff08;先查浏览器的DNS缓存&#xff0c;再查DNS服务器…

虚拟磁盘存储方式:单个文件 Or 多个文件?

文章目录3.虚拟磁盘存储方式&#xff1a;单个文件 Or 多个文件&#xff1f;3.1.拆分成多个文件3.2.存储为单个文件&#xff08;推荐&#xff09;3.2.1“单个文件”选项会立即占用100G吗&#xff1f;3.2.2“单个文件”选项下&#xff0c;如何在Win10中看到空间占用&#xff1f;总…

慢查询处理SOP

应急 如果影响到了核心业务&#xff0c;则kill该慢查询分析 通过explain语句查询sql的执行策略&#xff0c;主要关注type、keys、rows三个字段&#xff0c;type代表查询的类型&#xff08;能够帮助判断是否使用到了索引&#xff0c;最差得是全索引扫描index&#xff0c;不能是全…

[数字信号处理-入门] 时域分析

[数字信号处理-入门] 时域分析 个人导航 知乎&#xff1a;https://www.zhihu.com/people/byzh_rc CSDN&#xff1a;https://blog.csdn.net/qq_54636039 注&#xff1a;本文仅对所述内容做了框架性引导&#xff0c;具体细节可查询其余相关资料or源码 参考文章&#xff1a;各…

【毕业设计】基于python的遥感图片识别沙漠湖泊和森林基于CNN深度学习的遥感图片识别沙漠湖泊和森林

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

【计算机毕业设计案例】基于人工智能训练手写数字识别基于cnn训练手写数字识别

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

索引建立的原则

对经常作为查询条件的字段&#xff0c;排序的字段&#xff0c;具有高区分度的字段建立索引建立索引时基于最左前缀匹配原则尽量使用覆盖索引对于数据唯一性保障需求&#xff0c;可以使用唯一索引

python基于django的基于微信小程序的校园跑腿系统 校园快递代取系统97h4937r

目录 基于Django与微信小程序的校园跑腿系统摘要 关于博主开发技术路线相关技术介绍核心代码参考示例结论源码lw获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01; 基于Django与微信小程序的校园跑腿系统摘要 校园跑腿系统结合Django后端框架与微…

投资理财智能助手的基本概念

投资理财智能助手的基本概念 关键词:投资理财智能助手、人工智能、金融科技、个性化服务、数据驱动 摘要:本文深入探讨了投资理财智能助手的基本概念,旨在为读者全面介绍这一新兴领域。首先阐述了研究的目的和范围,明确预期读者,概述文档结构并解释相关术语。接着详细介绍…

【计算机毕业设计案例】基于深度学习CNN图像识别昆虫类别基于CNN图像识别昆虫类别

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

Bitwise AND of Numbers Range - 题解与思路

题目链接&#xff1a;Bitwise AND of Numbers Rangeleetcode​ 题目与直觉理解 题目&#xff1a;给定两个整数 left 和 right&#xff0c;表示闭区间 [left, right]&#xff0c;返回区间内所有整数的按位与结果。leetcode​ 约束&#xff1a;0 < left < right < 2^31…

python基于django的基于微信小程序的私房菜定制上门服务系统_私厨预约系统u7r6v9t1

目录系统概述核心功能技术架构创新点应用价值关于博主开发技术路线相关技术介绍核心代码参考示例结论源码lw获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;系统概述 该系统基于Python的Django框架开发&#xff0c;结合微信小程序前端&#xff…

NuttX RTOS是什么?

NuttX RTOS是什么&#xff1f; 本文来自于我关于各大 RTOS 科普系列文章。欢迎阅读、点评与交流~ 1、实时操作系统RTOS是什么&#xff1f; 2、常见的RTOS&#xff08;实时操作系统&#xff09;介绍 3、FreeRTOS 简介 4、Azure RTOS ThreadX 简介 5、NuttX RTOS是什么&#xff1…

AI驱动的软件需求分析与管理

AI驱动的软件需求分析与管理 关键词:AI、软件需求分析、软件需求管理、自然语言处理、机器学习 摘要:本文深入探讨了AI驱动的软件需求分析与管理这一前沿领域。首先介绍了该主题的背景,包括目的和范围、预期读者等内容。接着阐述了核心概念,通过文本示意图和Mermaid流程图展…

【计算机毕业设计案例】机器学习基于python深度学习的印刷体数字和字母识别基于python深度学习的印刷体数字和字母识别

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

python基于django的家庭医生预约服务软件设计_7mr4t5lr

目录基于Django的家庭医生预约服务软件设计关于博主开发技术路线相关技术介绍核心代码参考示例结论源码lw获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;基于Django的家庭医生预约服务软件设计 家庭医生预约服务软件旨在为用户提供便捷的在线预…