后面还有一个节点5(这个节点5是因为线程二中已经rehash完毕之后留下的),此时他又会把节点5放在线程一中的首部此时也就是5---->9----5(后面这部分的9–>5是保留的第三个状态留下的),到这里就形成了死循环
概述 大神陈皓已经在疫苗:JAVA HASHMAP的死循环一文中详细描述了HashMap多线程下产生死循环的原因,我仔细研读了这篇大作,做了一些笔记,加上自己的一些理解 整理出一些信息,发出来与大家交流交流...HashMap存储的数据结构 陈皓在Hash表数据结构这一节提到了HashMap的数据结构以及扩容问题,关于这一点我之前写过的 HashMap的put和get方法原理和HashMap扩容已经有详细的描述了...多线程rehash的时候如何造成闭环链表 rehash源代码 这里写图片描述 这里写图片描述 正常的rehash过程 数据准备 在size=2的HashMap中按照顺序添加...的put和get方法原理和HashMap扩容) 这里写图片描述 这个时候,如果有个get请求,就有可能发生死循环,一直在链表中绕来绕去的,没法终止。...原文链接 HashMap多线程下发生死循环的原因 发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/108167.html原文链接:https://javaforall.cn
HashMap扩容死循环问题源码分析问题(jdk1.7) 一、首先hashmap单线程正常扩容 遍历每个数组,依次遍历每个数组的链表,根据头插法由原来的1,2,3 变为了3,2,1 二、hashmap...多线程扩容死循环问题 两个线程 e1 ,e2 此时 线程一先执行,但线程二的指向发生改变,改为线程变换后的具体存储;初始的e2指向0号位的1,但经过线程一的变换指向了2号位的1了,next也发生改变
介绍 之前的文章已经分析了HashMap在JDK1.7的实现,这篇文章就只分析HashMap死循环形成的原因 死循环形成是在扩容转移元素的时候发生的 void resize(int newCapacity...结构如下 image.png 环形链表形成,此时无论将线程1还是线程2的table设置为newTable,当调用get方法执行到这条链上时,死循环形成。
HashMap 的长度为什么是2的幂次方 为了能让 HashMap 存取高效,尽量较少碰撞,也就是要尽量把数据分配均匀。...这也就解释了 HashMap 的长度为什么是2的幂次方。 这个算法应该如何设计? 首先,我们可能会想到采用%取余的操作来实现。...则等价于与其除数减一的与(&)操作(hash%length == hash&(length-1),前提是 length 是2的 n 次方;), 而且采用二进制位操作 &,相对于%能够提高运算效率,这同样解释了...HashMap 多线程操作导致死循环问题 主要原因是由于多并发情况下, rehash 操作可能会造成元素间形成一个循环链表。...参考阅读:JAVA HASHMAP的死循环
在JDK1.8之前的版本中,HashMap的底层实现是数组+链表。...当调用HashMap的put方法添加元素时,如果新元素的hash值或key在原Map中不存在,会检查容量size有没有超过设定的threshold,如果超过则需要进行扩容,扩容的容量是原数组的两倍,具体代码如下...newTable[i]; newTable[i] = e; e = next; } } } 假设一个HashMap...的初始容量是4,使用默认负载因子0.75,有三个元素通过Hash算法计算出的数组下标都是2,但是key值都不同,分别是a1、a2、a3,HashMap内部存储如下图: ?...transfer方法后,a1元素和a2元素形成了循环引用,此时无论将T1的Entry数组还是T2的Entry数组返回作为扩容后的新数组,都会存在这个环形链表,当调用get方法获取该位置的元素时就会发生死循环
在淘宝内网里看到同事发了贴说了一个CPU被100%的线上故障,并且这个事发生了很多次,原因是在Java语言在并发情况下使用HashMap造成Race Condition,从而导致死循环。...问题的症状 从前我们的Java代码因为一些原因使用了HashMap这个东西,但是当时的程序是单线程的,一切都没有问题。...我们简单的看一下我们自己的代码,我们就知道HashMap被多个线程操作。而Java的文档说HashMap是非线程安全的,应该用ConcurrentHashMap。 但是在这里我们可以来研究一下原因。...Hash表数据结构 我需要简单地说一下HashMap这个经典的数据结构。...我假设了我们的hash算法就是简单的用key mod 一下表的大小(也就是数组的长度)。
转自:Aaron_涛 链接:blog.csdn.net/qq_33330687/article/details/101479385 是否你听说过JDK8之后HashMap已经解决的扩容死循环的问题,...虽然HashMap依然说线程不安全,但是不会造成服务器load飙升的问题。...我勒个去,HashMap,猜测八成死循环了,但是我们使用的JDK8,在8中通过栈封闭的链表替换,解决了扩容死循环的问题。疑惑,继续往下看。...根据堆栈信息,root方法是问题所在,点开HashMap源码 ?...后续打算深入研究一下红黑树什么场景会造成这个原因。 最后,无论什么并发场景请别使用HashMap,ConcurrentHashmap大法好
HashMap的死循环问题只在JDK1.7版本中会出现,主要是HashMap自身的工作机制,再加上并发操作,从而导致出现死循环。JDK1.8以后,官方彻底解决了这个问题。...1、数据插入原理 在分析原因之前,我先带大家了解一下JDK1.7中HashMap插入数据的原理,来看动画演示: 由于JDK 1.7中HashMap的底层存储结构采用的是数组 加 链表的方式。...2、导致死循环的原因 接下来,我通过动画演示的方式,带大家彻底理解造成HashMap死循环的原因。...4、总结 HashMap死循环只发生在JDK1.7版本中,主要原因是JDK1.7中的HashMap,在头插法 加 链表 加 多线程并发 加 扩容这几个情形累加到一起就会形成死循环。...在JDK1.8中,HashMap改成了尾插法,解决了链表死循环的问题。 以上就是关于HashMap死循环原因的分析。
是否你听说过JDK8之后HashMap已经解决的扩容死循环的问题,虽然HashMap依然说线程不安全,但是不会造成服务器load飙升的问题。 然而事实并非如此。...我勒个去,HashMap,猜测八成死循环了,但是我们使用的JDK8,在8中通过栈封闭的链表替换,解决了扩容死循环的问题。疑惑,继续往下看。...根据堆栈信息,root方法是问题所在,点开HashMap源码 ?...好嘛,load飙高,代码有个for语句,我觉得铁定死循环了,看代码情况只可能是两个红黑树节点的父亲节点相互引用才可以导致无法走出这个for语句。 然而这都是我的猜测,我没有证据。...后续打算深入研究一下红黑树什么场景会造成这个原因。 最后,无论什么并发场景请别使用HashMap,ConcurrentHashmap大法好。
HashMap死循环 首先小伙伴要明确:死循环问题在JDK 1.8 之前是存在的,JDK 1.8 通过增加loHead和loTail进行了修复。...在JDK 1.7及之前 HashMap在并发情况下导致循环问题,致使服务器cpu飙升至100%,那么今天就来解析一下线程不安全的HashMap在高并发的情况下是如何造成死循环的。...要探究hashmap死循环的原因 首先要知道hashmap的源码 这样才能从根本上对hashmap进行理解 。 首先hashmap进行元素的插入,在元素个数达到阀值时: ?...下面这个方法就是出现死循环的方法了,下面请听我一一道来: ?...添加元素达到阀值后对hashmap进行扩容,走reaize方法,在对hashmap进行扩容时,又会调用一个transfer对旧的hashmap中的元素进行转移,那么我们今天要探究的死循环问题 就是发生在这个方法里的
这里的16和2倍就保证了 HashMap 的容量是2的 n 次幂,那么这样设计的原因是什么呢? 原因一:与运算高效 与运算 & ,基于二进制数值,同时为1结果为1,否则就是0。...HashMap初始容量为什么是2的n次幂及扩容为什么是2倍的形式 HashMap 是如何导致死循环的 HashMap 会导致死循环是在 jdk1.7 中,由于扩容时的操作是使用头插法,在多线程的环境下可能产生循环链表...原因分析 在了解来龙去脉之前,我们先看看HashMap的数据结构。...在内部,HashMap使用一个Entry数组保存key、value数据,当一对key、value被加入时,会通过一个hash算法得到数组的下标index,算法很简单,根据key的hash值,对数组的大小取模...HashMap 底层实现、加载因子、容量值及死循环 第二步,移动节点b ? HashMap 底层实现、加载因子、容量值及死循环 注意,这里的顺序是反过来的,继续移动节点c ?
今天研读Java并发容器和框架时,看到为什么要使用ConcurrentHashMap时,其中有一个原因是:线程不安全的HashMap, HashMap在并发执行put操作时会引起死循环,是因为多线程会导致...HashMap的Entry链表形成环形数据结构,查找时会陷入死循环。...纠起原因看了其他的博客,都比较抽象,所以这里以图形的方式展示一下,希望支持!...(1)当往HashMap中添加元素时,会引起HashMap容器的扩容,原理不再解释,直接附源代码,如下: /** * * 往表中添加元素,如果插入元素之后,表长度不够,便会调用resize...并发时,会引起死循环的根本原因所在,下面结合transfer的源代码,说明一下产生死循环的原理,先列transfer代码(这是里JDK7的源偌),如下: /** * Transfers
今天研读 Java 并发容器和框架时,看到为什么要使用 ConcurrentHashMap 时,其中有一个原因是:线程不安全的HashMap, HashMap在并发执行put操作时会引起死循环,是因为多线程会导致...HashMap的Entry链表形成环形数据结构,查找时会陷入死循环。...纠起原因看了其他的博客,都比较抽象,所以这里以图形的方式展示一下,希望支持!...(1)当往HashMap中添加元素时,会引起HashMap容器的扩容,原理不再解释,直接附源代码,如下: /** * * 往表中添加元素,如果插入元素之后,表长度不够,便会调用resize...并发时,会引起死循环的根本原因所在,下面结合transfer的源代码,说明一下产生死循环的原理,先列transfer代码(这是里JDK7的源码),如下: /** * Transfers all
作者:Aaron_涛 blog.csdn.net/qq_33330687/article/details/101479385 是否你听说过JDK8之后HashMap已经解决的扩容死循环的问题,虽然HashMap...我勒个去,HashMap,猜测八成死循环了,但是我们使用的JDK8,在8中通过栈封闭的链表替换,解决了扩容死循环的问题。疑惑,继续往下看。...根据堆栈信息,root方法是问题所在,点开HashMap源码 ?...好嘛,load飙高,代码有个for语句,我觉得铁定死循环了,看代码情况只可能是两个红黑树节点的父亲节点相互引用才可以导致无法走出这个for语句。 然而这都是我的猜测,我没有证据。...后续打算深入研究一下红黑树什么场景会造成这个原因。 最后,无论什么并发场景请别使用HashMap,ConcurrentHashmap大法好 ?
在网上搜资料时候然后发现网上都说1.7版本的HashMap会发生死链也就是死循环,但是在HashMap中也会产生死循环,接下来直接看代码吧 代码 类名字我忘记改了这是我以前看park时候弄的但是这不重要...当你运行 public class parkAndUnpark { static Map map = new HashMap(); static class...; } } 好了这里会阻塞住 但是可能你没阻塞住所以多运行几次 实验jps查看运行线程 jstack 使用jstack分析堆栈快照 两个线程都在运行但是没有输出同时也没有结束这就产生了死循环
面试合集:https://gitee.com/mydb/interview 本篇的这个问题是一个开放性问题,HashMap 除了死循环之外,还有其他什么问题?...总体来说 HashMap 的所有“问题”,都是因为使用(HashMap)不当才导致的,这些问题大致可以分为两类: 程序问题:比如 HashMap 在 JDK 1.7 中,并发插入时可能会发生死循环或数据覆盖的问题...1.死循环问题 死循环问题发生在 JDK 1.7 版本中,形成的原因是 JDK 1.7 HashMap 使用的是头插法,那么在并发扩容时可能就会导致死循环的问题,具体产生的过程如下流程所示。...1.1 死循环执行流程一 死循环是因为并发 HashMap 扩容导致的,并发扩容的第一步,线程 T1 和线程 T2 要对 HashMap 进行扩容操作,此时 T1 和 T2 指向的是链表的头结点元素 A...T1 执行完之后的顺序是 B 到 A,而 T2 的顺序是 A 到 B,这样 A 节点和 B 节点就形成死循环了,这就是 HashMap 死循环导致的原因。
那么面试官就会紧接着问道,为什么hashmap不是线程安全的,会造成什么问题么?于是面试者就回答:HashMap在并发情况下的put操作会造成死循环。...这时候就会被面试官问:HashMap在并发为什么造成死循环? 很多面试者这时候就会一脸懵。没有过相关经验和深入的理解源码是很难回答这个问题的。...下面我们就通过HahMap源码来验证下,多线程并发put操作为何会生成环形链表,产生死循环。...可以看到扩容后的散列表中链表成环,如果这时候执行get()方法查询,就会导致死循环。 总结 HashMap的方法不是线程安全的。...HashMap在并发执行put操作时发生扩容,可能会导致节点丢失,产生环形链表等情况。 节点丢失,会导致数据不准 生成环形链表,会导致get()方法死循环。
之前说过hashmap在jdk1.7的时候会造成链表头插法导致的死循环,那么是怎么造成的呢?本文会详细解释。...如下图: 于是当我们的线程A调用get()方法时,如果下标映射到3处,则会出现死循环。
简介 当HashMap的容量告急时,HashMap会 resize 进行扩容,扩容的过程就是将 table[] 数组放大两倍,然后通过 transfer 方法进行数据转移,从老的 table 转移到新的...补充HashMap结构 HashMap 是一个数组加链表的结构,一个数据put入 HashMap 先计算它的 hashcode, 然后取模后得到其在 table 数组的下标 index, 再将该数据节点放到...newtable[i] => A B Thread2:(没抢到CPU时间没变化) e = C next = null ========= newtable[i] => B => A 死循环...null) hiHead.treeify(tab); } } } 总结: 虽然修复了死循环的...BUG,但是HashMap 还是非线程安全类,仍然会产生数据丢失等问题。
领取专属 10元无门槛券
手把手带您无忧上云