其他分享
首页 > 其他分享> > HashMap死循环分析-基于JDK1.7

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,Thread,JDK1.7,next,链表,死循环
来源: https://www.cnblogs.com/tanyf/p/15068408.html