news 2026/7/10 12:42:24

jdk1.7 在多线程下扩容可能导致的死循环问题

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
jdk1.7 在多线程下扩容可能导致的死循环问题

首先先看看 hashmap 在jdk1.7 下扩容的核心方法

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; // 断开旧数组的引用,虽然不是必须的,但有助于GC // 遍历链表,把链表上的节点一个一个摘下来,重新放到新数组里 do { // 【关键点1】先保存下一个节点,防止待会链表断了找不到后面的人 Entry<K,V> next = e.next; // 计算这个节点在新数组中的下标 int i = indexFor(e.hash, newCapacity); // 【关键点2】头插法核心:将当前节点 e 的 next 指向新数组位置原本的头节点 e.next = newTable[i]; // 【关键点3】将新数组该位置的头指针指向 e(e 变成了新的头节点) newTable[i] = e; // 【关键点4】继续处理旧链表的下一个节点 e = next; } while (e != null); } } }

可以看到,jdk1.7 版本下的扩容依靠的是头插法实现元素搬移

头插法 的特点:假设旧数组某个位置的链表是A -> B -> C。 因为代码逻辑是:每次把新来的元素插到最前面(e.next = newTable[i]然后newTable[i] = e)。 所以搬运到新数组后,顺序会倒置,变成C -> B -> A

为什么JDK 1.7用头插法? 设计者当时认为,后插入的数据被访问的概率更高(热点数据),放在头部查得快。但这在多线程下埋下了祸根。

那其实在多线程的情况下就会有问题了,举个例子:

假设有两个线程Thread 1Thread 2同时在扩容。 旧链表结构:A -> B。 线程 1 执行到你注释的那一行挂起了(Paused):

Entry<K,V> next = e.next; // 线程1在这里卡住了! // 此时对于线程1来说: e = A, next = B
接下来可能发生的事情:
  1. 线程 2 抢占 CPU 完成了扩容
    • Thread 2 把AB都搬到了新数组。
    • 注意:因为是头插法,顺序反了
    • 在新内存里,现在的链表结构是:B -> A(B 指向 A,A 指向 null)。
  1. 线程 1 醒来继续执行
    • Thread 1 里的变量还停留在挂起前的状态:e = Anext = B
    • Thread 1 开始干活:
      • 将 A 指向 B
      • 头节点变成 A
      • 此时 A 指向 B,B 指向 A(死循环开始)
  1. 线程 1 接着处理 B,B 头插当头节点,此时 B 指向 A,A 指向 B
  2. 然后接着处理 A,A 头插当头节点,此时 A 指向 B,B 指向 A
  3. 然后循环往复 A,B 轮流当头节点,死循环

如图:


版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/10 11:08:30

EmotiVoice情感过渡平滑性测试:避免情绪跳跃突兀

EmotiVoice情感过渡平滑性测试&#xff1a;避免情绪跳跃突兀 在虚拟偶像的直播中&#xff0c;一个角色从温柔低语突然切换到愤怒咆哮&#xff0c;却没有任何铺垫——这种“情绪断层”不仅让观众出戏&#xff0c;更暴露了当前许多语音合成系统的深层缺陷。尽管现代TTS技术已经能…

作者头像 李华
网站建设 2026/7/10 11:03:04

3步搞定Windows MPV播放器专业配置:告别复杂设置的高效方案

3步搞定Windows MPV播放器专业配置&#xff1a;告别复杂设置的高效方案 【免费下载链接】mpv-config 本项目为 windows 下 mpv 播放器的配置文件 (This project is the configuration file of mpv player on Windows) 项目地址: https://gitcode.com/gh_mirrors/mp/mpv-confi…

作者头像 李华
网站建设 2026/7/9 18:40:20

开源项目管理软件战略指南:企业级功能选择决策框架

开源项目管理软件战略指南&#xff1a;企业级功能选择决策框架 【免费下载链接】openproject OpenProject is the leading open source project management software. 项目地址: https://gitcode.com/GitHub_Trending/op/openproject 在数字化转型浪潮中&#xff0c;开源…

作者头像 李华
网站建设 2026/7/10 12:08:37

Pytest参数化魔法:告别重复代码的Python测试革命

Pytest参数化魔法&#xff1a;告别重复代码的Python测试革命 【免费下载链接】junit4 A programmer-oriented testing framework for Java. 项目地址: https://gitcode.com/gh_mirrors/ju/junit4 还在为每个测试场景写一个测试函数而抓狂吗&#xff1f;&#x1f92f; 当…

作者头像 李华
网站建设 2026/7/9 23:03:29

【打靶日记】HackMyVm 之 Listen

主机发现 ┌──(root㉿xhh)-[~/Desktop/xhh/HMV/listen] └─# arp-scan -I eth1 -l192.168.56.147 08:00:27:2a:db:7b PCS Systemtechnik GmbH主机地址为&#xff1a;192.168.56.147 端口扫描 ┌──(root㉿xhh)-[~/Desktop/xhh/HMV/listen] └─# nmap 192.168.56…

作者头像 李华
网站建设 2026/7/9 17:03:40

7天精通时序模型智能训练:从过拟合陷阱到高效优化实战

7天精通时序模型智能训练&#xff1a;从过拟合陷阱到高效优化实战 【免费下载链接】Time-Series-Library A Library for Advanced Deep Time Series Models. 项目地址: https://gitcode.com/GitHub_Trending/ti/Time-Series-Library &#x1f680; 你是否正在为这些训练…

作者头像 李华