记java7 HashMap的transfer()方法中的疑惑

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013066244/article/details/88021093

环境

java:1.7

前言

之前知道HashMap会产生死循环,但是时间长了,我又忘了具体的原因;
我想估计是我没有彻底了解其原理造成的;
所以我又看了下java7的源码,并参考疫苗:JAVA HASHMAP的死循环,随便记录下,我产生的一些疑惑;

主要代码

do {
    Entry<K,V> next = e.next; // <--假设线程一执行到这里就被调度挂起了
    int i = indexFor(e.hash, newCapacity);
    e.next = newTable[i];
    newTable[i] = e;
    e = next;
} while (e != null);

根据博文的例子:

假设线程一:执行到这一句就挂起来了Entry<K,V> next = e.next;
然后是线程二:把这部分代码已经执行完毕了;

此时链表的结构如下:

在这里插入图片描述
此时,我有个疑问:

疑问线程一被调度回来执行时,第一次执行e.next = newTable[i]时; 此时不应该是 e.next = 7吗?
如上图,此时newTable[i]3的位置上,不是已经有值了?我感觉,这段代码,会一直死循环下去;

答案: 怪我悟性不够,newTable[]是在每个线程里new出来的,属于线程私有的;所以,第一次,里面并没有值(或者是随机的值);

疑问循环产生的原因

:我是这么认为的,之所以会产生这种死循环,①是每次扩容时,链表都发生了倒置,导致原先的next都存的是它们前一个元素。为发生环形链表埋下伏笔;②链表插入的方式,其采用的是头插入,每次插入新元素,都是放在最前面的; 不过也正式因为其采用头插入,所以才会发送了链表倒置;这是不是告诉我,假设我以后用到链表时,最好不要用头插入的方式,来新增元素。

参考地址:

Java 8系列之重新认识HashMap
疫苗:JAVA HASHMAP的死循环

猜你喜欢

转载自blog.csdn.net/u013066244/article/details/88021093