jdk1.7中hashMap扩容导致死循环问题原因分析

关于HashMap扩容造成死循环的介绍 一、造成死循环的原因 HashMap扩容导致死循环的主要原因在于扩容后链表中的节点在新的hash桶使用头插法插入。新的hash桶会倒置原hash桶中的单链表,那么在多个线程同时扩容的情况下就可能导致产生一个存在闭环的单链表,从而导致死循环。 在JDK1.8中,HashMap是不会造成死循环的,因为在JDK1.8中,采用的是尾插法,保证了链表的顺序与之前一致。而且在1.8中链表过长时会转换为红黑树,... 阅读详情

导致死循环的根源是在resize的时候进行元素转移的时候有概率会出现;
先说结论:导致问题的根本原因是使用头插法;
先贴出来源码:
但是哪怕你不看源码也没关系;

void transfer(Entry[] newTable, boolean rehash) {
    int newCapacity = newTable.length;
    for (Entry<K,V> e : table) {
        while(null != e) {
            Entry<K,V> next = e.next;
            if (rehash) {
                e.hash = null == e.key ? 0 : hash(e.key);
            }
            int i = indexFor(e.hash, newCapacity);
            e.next = newTable[i];
            newTable[i] = e;
            e = next;
        }
    }
}

这里呢好多文章通过举例子,画数据结构变化过程的图来进行讲解。不够形象,不易理解。这里我通过一个生活模型来进行讲解;

旅游公司维护旅游路线模型;

如下图,图中路线池子对应的就是hashMap中的数组,每个旅游路线的链表就是hashMap中的hash碰撞产生的链表;
在这里插入图片描述

故事是这样的:游客买完了某个旅游路线后,旅游公司会开大巴把你拉到你购买的起点,然后游客自己跟着路标进行旅游即可。旅游公司一直运营的很好。但是偶尔会有时候用户会 投诉说路线有问题,把我们当傻子一样困死在线路中; 但是这种现象经常出现在新加了景点,然后重新维护旅游路线的路标时候,(这里也就对应的是hashMap进行添加元素并且扩容的场景);
我们知道旅游线路都是带有一定文化主题的。在一个线路中的景点在重新维护的的时候很可能还是在一组。但是为了防止游客觉得没有新意,往往仅仅会给路线改个名字,然后把线路倒过来,重新设置路标,然后继续使用(头插法)
后来经过分析原来是名字叫 病发 的领导经常喝酒,脑袋混了经常同时派多个人去维护同一个路线;

下面我们看看怎么出现问题的;我们已第一条旅游线路来举例子;也就是A->B->C这条路线;

这不这次 病发 先派 小红 去把1路线的路标倒过来排,并且改名为15路线;然后他没过1秒钟就忘了,然后又派 小黑 也去同时维护同一条路线;
小红是个急性子,想赶快维护好下班回家。小黑是个佛系躺平青年,慢悠悠的弄;

时间小红小黑
1分钟到达A到达A
2分钟1.记下下一个要去处理的景点是B,2.把A挪到15路线开头,3,把A的路标设置为空 在这里插入图片描述1.把A挪到15路线开头,2.记下下一个景点是B,把A的路标设置为空 ,并前往B,在去B的的路上玩起了王者荣耀在这里插入图片描述
3分钟到达B,记下下一个景点C,把B挪到15路线,并把B的路标设置为A (头插法) 在这里插入图片描述AB路上王者荣耀
4分钟到达C,发现没有下一个景点了,把C挪到15路线,并把C的路标设置为B 在这里插入图片描述AB路上要输了,郁闷的往B景点走
5分钟完活,赶紧下班回家到达B,把B设置到15路线,把B的下一个景点设置为A(头插法),然后发现下一个要处理的节点是A,前往A在这里插入图片描述
6分钟到家了到达A,把A设置到15路线,记下当前A的下一个节点是空(心里开心了起来要完工了),然后把A的下一个节点设置为15的当前节点B 在这里插入图片描述
7分钟到家了完工,在回办公室的路上再开了一局
第二天又有投诉我*你个**

最后由小黑维护完成后,景点的路标会出现a指向b,b指向a的情况
在这里插入图片描述
到这里就弄明白了为什么hashMap会在并发场景下导致死循环的问题

5张图讲明白JDK1.7下的HashMap死循环(原理+实战) 目录 情景再现 网络上很多文章说HashMap死循环都是理论分析,其一是没有自己实验过,甚至给出的实验程序都是错误的,不能再现死循环的BUG,其二是给出的示意图不够详细,很多细节忽略了让人难以理解,本文在前人总结的基础上摸索出了实现死循环的方法,记录成文。 死循环原因 我们首先思考一下在什么样的情况下HashMap会死循环,死循环的原因不外乎是在多线程的同时扩容,在JDK 1.7的HashMap中,当hash冲突时,采用头插法拉链表,所谓头插法,即在每次都在链表头部(即桶中)插入最后添加的数据 当触发扩容 阅读详情

相关推荐

HashMap jdk1.7 高并发导致死循环

最近的几次面试中,我都问了是否了解HashMap在并发使用时可能发生死循环,导致cpu100%,结果让我很意外,都表示不知道有这样的问题,让我意外的是面试者的工作年限都不短。 由于HashMap并非是线程安全的,所以在高并发的情况下必然会出现问题,这是一个普遍的问题,虽然网上分析的文章很多,还是觉得有必须写一篇文章,让关注我公众号的同学能够意识到这个问题,并了解这个死循环是如何产生的。 如果是...

Top5软件工程硕士,先后在京东、字节从事多年Java后端开发、实时和离线大数据开发 1425

jdk1.7 hashmap死循环

HashMap死循环只发生在JDK1.7版本中,主要原因是JDK1.7中的HashMap,在头插法 加 链表 加 多线程并发 加 扩容这几个情形累加到一起就会形成死循环。多线程环境下建议采用ConcurrentHashMap替代。

weixin_48913290的博客 1410

用Pixhawk 2.4.8和PX4 1.13,从零搭建你的第一支无人机编队(附避坑清单)

本文详细介绍了如何使用Pixhawk 2.4.8飞控和PX4 1.13固件从零搭建低成本无人机编队系统。涵盖硬件选型、固件配置、多机通信和编队飞行逻辑开发的全流程,特别针对学生和爱好者提供实战验证的避坑方案,帮助实现多机协同飞行。

weixin_27219587的博客 403

图解JDK1.7中HashMap头插法扩容造成的死循环问题

HashMap是线程不安全的,在并发使用HashMap时很容易出现一些问题,其中最典型的就是并发情况下扩容之后会发生死循环,导致CPU占用100%。同时,这也是一个高频面试题。本文通过解读HashMap源码并结合实例,来具体分析HashMap扩容发生的死循环问题。

frozenpenguin的博客 4031

告别蓝牙音质妥协:用ESP32和PCM5102搭建WiFi无损音频播放器(附完整代码)

本文详细介绍了如何利用ESP32微控制器和PCM5102 DAC芯片构建一套完整的WiFi无损音频流媒体系统,彻底摆脱蓝牙协议的音质束缚。从硬件原理到软件实现,包括核心器件选型、电路设计、I2S音频驱动实现以及系统优化方案,帮助音频发烧友实现高保真无线音频传输。

weixin_30733003的博客 542

一文详解Stata重复测量方差分析的概念、原理、适用情形以及操作命令实现、对结果的解读、操作注意事项 附零基础小白友好入门Stata统计学/计量经济学学习路径

重复测量方差分析(Repeated Measures ANOVA)适用于同一受试者在不同时间点或条件下的多次测量数据,如疗效跟踪和跨条件对比研究。其核心特征包括:数据结构为每个受试者多个观测值,数据具有相关性(违反独立性假设),变异分解为个体间和个体内变异。关键假设包括正态性、方差齐性和球形性(通过Mauchly检验验证)。适用场景包括纵向研究和小样本追踪,但不适用于存在滞留效应或学习效应显著的数据。操作步骤涉及数据准备(宽/长格式转换)、正态性与球形性检验、主分析命令(单/多因素)及事后检验。

m0_72274883的博客 1565

【透彻】java关于HashMap多线程扩容导致死循环(JDK1.7)的详细过程

本篇主要通过图解的方式,解释了为什么JDK1.7中的HashMap在多线程情况下扩容可能死循环,也解释了JDK1.8如何解决这个问题。不得不说,画图是个很好的分析方式,根据代码,一步一步把结构图画出来,比对着代码瞎琢磨效果好多了。我在原文基础上把第二张图(多线程那张图)修改了一下,因为原作者画的图有些问题(原图的最后9个隔断应该是newTable的,而原作者给画成了table的)HashMap多线程扩容导致死循环(JDK1.7),为什么?- 知乎。.....................

HD243608836的博客 3550

【原创】下载RealEstate10K数据集原始视频的方法

目前互联网上能搜到下载RealEstate10K数据集原始视频的方法都已经不能用了,这篇博客介绍一种目前可用的下载RealEstate10K数据集原始视频的方法,并给出自动化的脚本代码。

沉迷单车的追风少年 2462

HashMap多线程扩容导致死循环解析(JDK1.7)

由于头插法的原因,再次执行头插法的时候会将原来的链表顺序反过来,所以当第一个线程执行完扩容之后会将顺序从。最后由于e等于null,退出循环,当下次遍历到该元素时就会进入死循环。1->2->3 到 3->2->1。线程二第一次执行插入结束后。线程二准备第二次循环结束后。线程二第二次执行插入结束后。线程二准备第二次循环结束后。线程二第三次执行插入结束后。线程二准备第三次循环结束后。

qq_51902025的博客 850

华为OD新系统机试真题 4.26 -最大化游戏试玩资格分发

华为OD机试新系统真题【最大化游戏试玩资格分发】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD新系统机试 4月26号真题【最大化游戏试玩资格分发】。

qq_45776114的博客 826

电磁场仿真软件:COMSOL Multiphysics_(17).时域与频域分析

时域和频域分析是电磁场仿真中非常重要的两种方法,每种方法都有其独特的应用场景和优势。时域分析适用于瞬态响应和宽带信号的分析,而频域分析则适用于稳态响应和窄带信号的分析。在COMSOL Multiphysics中,通过合理设置物理场接口、材料属性、边界条件、网格划分和求解器,可以高效地进行这两种分析,并通过傅里叶变换将时域结果转换为频域结果,进一步拓展仿真应用的范围。合理的性能优化措施,如网格划分优化和并行计算,可以显著提高仿真的效率和准确性。

kkchenjj的博客 1976

为什么JDK1.7的HashMap会出现扩容死链

JDK1.7版本的HashMap在多线程的情况下扩容出现死循环(扩容死链),根本原因是:HashMap在进行扩容时需要进行数据转移,jdk1.7的版本数据转移使用的是头插法(链表的数据从头插入)。

suweijie的博客 760

【WRF理论第十四期】 VEGPARM.TBL 文件详解

WRF 读取 VEGPARM.TBL 文件

WW、forever的博客 576

jdk1.7HashMap链表头插法导致的死循环

jdk1.7的HashMap的源码分析参考我之前整理的连接https://blog.csdn.net/thqtzq/article/details/90146880,之前也有整理头插法导致的死循环,这里再整理一下。参考连接:https://coolshell.cn/articles/9606.html 扩容的核心源码如下: void transfer(Entry[] newTable, boole...

手写ArrayList 1万+

手撕Lua字节码:从黑盒到透明

lua 字节码 怎么‘手撕’一个 chunk 看看里面啥样?我手里有一个.luac或出来的二进制字节码,想知道里面到底是什么结构、哪些字段、有哪些指令,怎么一步一步“拆箱”,从一个黑盒变成有迹可循的东西?也就是:不满足于只会loadpcall而是想亲眼看看一个 chunk 内部长啥样,甚至写点工具把它解析出来。这篇就用带你从“拿到一坨.luac不搞高深玄学,尽量让你看完就能自己动手。注:以 Lua 5.3/5.4 为主,细节各版本略有不同,但大体套路是一致的。

本博客聚焦游戏开发技巧、创业实战心得及大学热门课程干货。这里既有技术深度,也有思维广度,无论你是开发者、创业者还是高校学子,都能在这里找到适合自己的成长之路! 99

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

JDK1.8后HashMap多线程下扩容死循环解决

JDK1.8后HashMap多线程下扩容死循环解决HashMap的底层数据原理扩容解决死循环 HashMap的底层数据原理 Hash Map采用的是散列表来记录数据,可以把散列表想象成table[]数组,每个下标下标保存一个链表的head,用链表解决hash值冲突的问题,每次添加调用put(key , value),先得到key的hash值然后用hash & (table的长度)来得到这个...

weixin_41156348的博客 9978

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

JDK7 HashMap多线程扩容导致的死循环问题

JDK7HashMap多线程扩容导致的死循环问题前言源码多线程扩容 前言 JDK8以前的HashMap,多线程扩容的时候可能会出现死循环,这个问题在JDK8得到了修复。本翔看了大半天JDK7HashMap扩容源码找这个问题,所以写篇博客记录记录。 源码 先来看看JDK7的HashMap扩容相关源码。 //扩容 void resize(int newCapacity) { Entry[] oldTable = table; int oldCapacity = oldTa

七里翔的博客 1410

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

jdk1.7 HashMap扩容时死循环问题

jdk1.7 hashmap在resize时进行扩容时,会导致死循环,主要是因为jdk1.7采用的是头插法 void transfer(Entry[] newTable, boolean rehash) { int newCapacity = newTable.length; for (Entry<K,V> e : table) { while(null != e) { Entry<K,V> next = e.next;

xby7437的博客 1万+

hashmap扩容线程安全问题_HashMap多线程扩容导致死循环(JDK1.7),为什么?

前言JDK1.7中的HashMap在多线程情况下扩容可能会导致死循环。本篇就这个问题进行讲解。扩容死循环前一篇深入的讲解了HashMap1.7扩容的过程,这里回顾一下在扩容过程中,单链表的表现,相关的代码如下void transfer(Entry[] newTable, boolean rehash) { int newCapacity = newTable.length; // ...

weixin_39797532的博客 1090

简单总结jdk1.7HashMap扩容死循环和jdk1.8优化

简单总结jdk1.7HashMap扩容死循环和jdk1.8优化jdk1.7 HashMap死循环原因扩容步骤死循环总结jdk1.8的改进jdk1.8仍然存在的问题 网上很多关于jdk1.7HashMap扩容死循环的博客, 但是很多都是贴了大量的代码和图, 这里只进行简单概括总结, 详细的还是需要自己看源码. jdk1.7 HashMap死循环原因 首先贴代码 (这个必要的还是要贴) void resize(int newCapacity) { .... transfer(ne

zzzgd_666的博客 1161

HashMap 在 JDK 1.7 中为什么会出现死循环

JDK1.7的HashMap在多线程扩容时存在死循环问题 摘要:JDK1.7的HashMap在多线程并发扩容时,由于使用头插法转移链表且未加锁,可能导致链表形成环形结构。具体表现为:多个线程同时进行resize操作时,对同一桶链表的节点转移顺序可能被打乱,最终形成e1→e2→e1的闭环链表,导致后续遍历时出现死循环。该问题在JDK1.8中通过改用尾插法和synchronized锁机制得以解决。

chenxuefeng_accp的专栏 1513

HashMap1.7扩容的时候采用头插法为什么会死循环

摘要:本文深入解析HashMap扩容机制及JDK1.7死循环问题。JDK1.8优化扩容采用位运算判断元素新位置(原地或移动旧容量距离),提升效率。重点剖析JDK1.7多线程扩容时头插法导致链表逆序,在并发操作下形成环形链表(如A→B→A)的死循环问题。JDK1.8改用尾插法保持链表顺序一致解决该问题,但HashMap仍非线程安全,建议多线程环境使用ConcurrentHashMap。全文从扩容原理到问题重现,完整呈现了HashMap核心机制及其演进。(150字)

多多的博客 1015

hashmap头插法和尾插法区别_HashMap扩容死循环问题

JDK 1.7 HashMap 扩容核心算法下面这是JDK 1.7中HashMap扩容时调用的核心代码,作用是将原hash桶中的节点转移到新的hash桶中:void transfer(Entry[] newTable) {Entry[] src = table;int newCapacity = newTable.length;for (int j = 0; j < src.length; ...

weixin_26516551的博客 3438

JDK1.7的HashMap链表死循环分析

在JDK1.7及以前的版本,如果在并发环境中使用HashMap保存数据,有可能会产生死循环的问题,造成cpu的使用率飙升。产生这个问题是因为JDK1.7及以前的版本中,HashMap扩容采用的是头插入,1.8做的改进是采用尾插法,所以不会造成死循环的问题。 首先,来看1.7扩容的代码: //进行扩容时方法 void resize(int newCapacity) { ...

八戒的博客 2646

为什么说JDK7中的hashMap使用头插法会导致死循环呢?

为什么说JDK7中的hashMap中使用的头插法会导致死循环

qq_66908247的博客 1259
上一篇: foolflow用思维组织代码
下一篇: 求最小差值算法题
掀衣怒码
博客等级 码龄6年 6粉丝 19原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值