jdk1.7hashmap扩容死循环问题解析

之前就知道1.7的hashmap在并发下是存在安全性问题的。
1、值可能会被覆盖
2、死循环的问题
虽然知道有问题,但是没有具体分析过。所以今天就本着好奇看看问题是怎么产生的。
为了看看问题,专门下载了1.7版本的jdk来看看源码

1.7版本源码片段
在这里插入图片描述

    void transfer(Entry[] newTable, boolean rehash) {
        int newCapacity = newTable.length;
        for (Entry<K,V> e : table) {
        	//链表的核心操作就在while循环里面
            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;
            }
        }
    }

理解一下while操作过程:
1、拿到了entry ==》 entry.next
2、hash操作拿到链表存储在数组上的位置index
3、头插法插数据
4、entry赋值为next,进行下一轮操作

多线程下怎么出现死循环的?

先看看hashmap结构
在这里插入图片描述

下面我们看一下链表操作的图解过程:
注:步骤二寻址过程默认几个entry刚好又一次连续放在一个index里面

在这里插入图片描述
如果thread2后完成扩容,我们可以看出两个问题:
1、entry3数据丢失;
2、entry1和entry2循环引用了;

注:死循环发生在哪儿?
我没去实际画图的时候,我猜想的是可能线程1和线程2在相互改对方的引用然后一直执行头部插入:1->2->1->2->1…所以到底啥时候会出现死循环呢?
1、下一次扩容的时候;扩容会一直取获取next,直到为null为止,循环引用就没了next为null的时候;CPU又傻逼了,环路上打转转。
2、get entry3的时候,因为entry3丢失了,然后在链表上依次寻找又找不到,然后cpu就开始在一个圈圈上打转转了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值