news 2026/5/21 0:34:03

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/5/11 16:08:35

WPF给类添加属性通知 INotifyPropertyChanged

public abstract class BaseModel : INotifyPropertyChanged{public event PropertyChangedEventHandler PropertyChanged;/// <summary>/// 属性改变&#xff0c;通知更新UI/// </summary>/// <remarks>/// 创建时间&#xff1a;2025-12-2 11:16:36&#xf…

作者头像 李华
网站建设 2026/5/2 3:14:52

从 “黑箱预测” 到 “可解释推理”,连信人格识别方案刷新行业认知

传统的人格测试依赖量表&#xff0c;需受试者的自我填写&#xff0c;易受主观偏差影响、耗时费力。而基于视觉人工智能的个体心理识别基本上停留在对情绪、表情、动作等外在观测指标的识别。基于短暂视频图像的人格识别在行业内极难实现&#xff0c;使用行业内顶尖的大模型&…

作者头像 李华
网站建设 2026/5/20 17:46:32

PortProxyGUI:Windows端口重定向的终极图形界面管理工具

PortProxyGUI&#xff1a;Windows端口重定向的终极图形界面管理工具 【免费下载链接】PortProxyGUI A manager of netsh interface portproxy which is to evaluate TCP/IP port redirect on windows. 项目地址: https://gitcode.com/gh_mirrors/po/PortProxyGUI 还在为…

作者头像 李华
网站建设 2026/5/10 13:42:57

ThinkPad T480终极改造:OpenCore完美运行macOS全攻略

ThinkPad T480终极改造&#xff1a;OpenCore完美运行macOS全攻略 【免费下载链接】t480-oc &#x1f4bb; Lenovo ThinkPad T480 / T580 / X280 Hackintosh (macOS Monterey 12.x & Ventura 13.x) - OpenCore 项目地址: https://gitcode.com/gh_mirrors/t4/t480-oc …

作者头像 李华
网站建设 2026/5/20 12:07:49

Citra模拟器终极使用手册:从零基础到精通的全方位指南

Citra模拟器终极使用手册&#xff1a;从零基础到精通的全方位指南 【免费下载链接】citra 项目地址: https://gitcode.com/GitHub_Trending/ci/citra 还在为3DS游戏无法在电脑上流畅运行而困扰吗&#xff1f;想要在更大屏幕上重温经典游戏却不知从何入手&#xff1f;这…

作者头像 李华
网站建设 2026/5/7 20:02:56

高斯泼溅、Unity渲染、技术指南:从入门到精通

高斯泼溅、Unity渲染、技术指南&#xff1a;从入门到精通 【免费下载链接】UnityGaussianSplatting Toy Gaussian Splatting visualization in Unity 项目地址: https://gitcode.com/gh_mirrors/un/UnityGaussianSplatting 高斯泼溅(Gaussian Splatting)作为2023年SIGGR…

作者头像 李华