其他分享
首页 > 其他分享> > jdk1.7中hashMap扩容导致死循环问题原理分析

jdk1.7中hashMap扩容导致死循环问题原理分析

作者:互联网

导致死循环的根源是在resize的时候进行元素转移的时候有概率会出现;
先说结论:导致问题的根本原因是使用头插法;
先贴出来源码:
但是哪怕你不看源码也没关系;

void transfer(Entry[] newTable, boolean rehash) {
    int newCapacity = newTable.length;
    for (Entry<K,V> e : table) {
        while(null != e) {
            Entry<K,V> next = e.next;
            if (rehash) {
                e.hash = null == e.key ? 0 : hash(e.key);
            }
            int i = indexFor(e.hash, newCapacity);
            e.next = newTable[i];
            newTable[i] = e;
            e = next;
        }
    }
}

这里呢好多文章通过举例子,画数据结构变化过程的图来进行讲解。不够形象,不易理解。这里我通过一个生活模型来进行讲解;

旅游公司维护旅游路线模型;

如下图,图中路线池子对应的就是hashMap中的数组,每个旅游路线的链表就是hashMap中的hash碰撞产生的链表;
在这里插入图片描述

故事是这样的:游客买完了某个旅游路线后,旅游公司会开大巴把你拉到你购买的起点,然后游客自己跟着路标进行旅游即可。旅游公司一直运营的很好。但是偶尔会有时候用户会 投诉说路线有问题,把我们当傻子一样困死在线路中; 但是这种现象经常出现在新加了景点,然后重新维护旅游路线的路标时候,(这里也就对应的是hashMap进行添加元素并且扩容的场景);
我们知道旅游线路都是带有一定文化主题的。在一个线路中的景点在重新维护的的时候很可能还是在一组。但是为了防止游客觉得没有新意,往往仅仅会给路线改个名字,然后把线路倒过来,重新设置路标,然后继续使用(尾插法)
后来经过分析原来是名字叫 病发 的领导经常喝酒,脑袋混了经常同时派多个人去维护同一个路线;

下面我们看看怎么出现问题的;我们已第一条旅游线路来举例子;也就是A->B->C这条路线;

这不这次 病发 先派 小红 去把1路线的路标倒过来排,并且改名为15;然后他没过1秒钟就忘了,然后又派 小黑 也去同时维护同一条路线;
小红是个急性子,想赶快维护好下班回家。小黑是个佛系躺平青年,慢悠悠的弄;

时间小红小黑
1分钟到达A到达A
2分钟1.记下下一个要去处理的景点是B,2.把A挪到15路线开头,3,把A的路标设置为空 在这里插入图片描述1.把A挪到15路线开头,2.记下下一个景点是B,把A的路标设置为空 ,并前往B,在去B的的路上玩起了王者荣耀在这里插入图片描述
3分钟到达B,记下下一个景点C,把B挪到15路线,并把B的路标设置为A (头插法) 在这里插入图片描述AB路上王者荣耀
4分钟到达C,发现没有下一个景点了,把C挪到15路线,并把C的路标设置为B 在这里插入图片描述AB路上要输了,郁闷的往B景点走
5分钟完活,赶紧下班回家到达B,把B设置到15路线,把B的下一个景点设置为A(头插法),然后发现下一个要处理的节点是A,前往A在这里插入图片描述
6分钟到家了到达A,把A设置到15路线,记下当前A的下一个节点是空(心里开心了起来要完工了),然后把A的下一个节点设置为15的当前节点B 在这里插入图片描述
7分钟到家了完工,在回办公室的路上再开了一局
第二天又有投诉我*你个**

最后由小黑维护完成后,景点的路标会出现a指向b,b指向a的情况
在这里插入图片描述
到这里就弄明白了为什么hashMap会在并发场景下导致死循环的问题

标签:15,hashMap,路标,jdk1.7,路线,旅游,景点,死循环
来源: https://blog.csdn.net/AngryCoding/article/details/117395198