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

2021/7/27 23:36:18

本文主要是介绍HashMap死循环分析-基于JDK1.7,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

咦,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的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程