首页 > 其他 > 详细

HashMap死循环分析-基于JDK1.7

时间:2021-07-28 09:50:08      阅读:21      评论:0      收藏:0      [点我收藏+]

咦,HashMap还会死循环么,一脸懵。在JDK1.8之前,HashMap是有可能出现死循环的,什么情况下会出现死循环呢?在put操作触发并发扩容的情况下可能会出现死循环,上源码

1.put()方法

技术分享图片

2.进入addEntry()方法

技术分享图片

3.进入resize()方法

技术分享图片

4.进入transfer()方法,出现死循环的原因就在其中

技术分享图片

假设有一个HashMap如下:

技术分享图片

现在有Thread-A和线程Thread-B对其进行扩容,Thread-A运行到transfer()方法中的Entry<k,v> next = e.next;的时候Thread-A被挂起,Thread-B进行扩容,进行第一轮循环如下:

技术分享图片

进入下一轮循环

技术分享图片

Thread-B完成了扩容,就在这个时候Thread-A被唤醒,而在Thread-A中是在Entry<k,v> next = e.next;的时候被挂起的,也就是那个时候,e是key3,next=e.next是key7,于是如下图:

技术分享图片

进行下一轮循环如下:

技术分享图片

此刻key7的next指向key3,进行下一轮循环如下:

技术分享图片

可以看到形成了一个循环链表,当你去get一个 key11、key15不存在的时候,就会形成死循环。

总结:HashMap之所以在并发扩容下形成死循环,是因为多个线程并发扩容时,一个线程先完成了扩容,将原本HashMap的链表重新散列到自己的表中,并且链表成了倒序,后一个线程扩容时,再一次散列搭到自己的表中,再次将倒序链表变成正序链表,于是形成了一个循环链表,当get落在这个桶上不存在的元素时,造成死循环。

 

HashMap死循环分析-基于JDK1.7

原文:https://www.cnblogs.com/tanyf/p/15068408.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!