JDK1.7中HashMap并发成环的原因

JDK1.7中HashMap存在并发成环的问题。问题发生在扩容搬运的时候,具体代码如下。

void transfer(Entry[] newTable, boolean rehash) {
    int newCapacity = newTable.length;
    //table是旧table,也就是扩容前的table
    for (Entry<K,V> e : table) {
        //e为槽位的头节点,通过头节点遍历槽位
        while(null != e) {
            Entry<K,V> next = e.next; 
            if (rehash) {
                e.hash = null == e.key ? 0 : hash(e.key);
            }
            //获得e在新table中位置
            int i = indexFor(e.hash, newCapacity); 
            
            //采用头插法
            //将e的next设置为newTable[i],也就是i对应的头节点
            //然后将e设置为newTable[i],也就是i对应的头节点
           
            //是一种头插做法
            e.next = newTable[i]; 
            newTable[i] = e; 
            e = next; 
        }
    }
}

如上图所示,如果线程1完成了槽位1的搬运,也就是将旧table[1]中的节点搬运到了新table[1]中。对应的排列为 b,a,null,此时b为新table[1]的头节点为b。

这时来了一个线程2也来搬运槽位1,这时,旧table中的头节点为a,按照头插法,会将a.next = newTable[i],这时线程1已经将新table[1]的头节点为a,也就是a.next = b。之前线程1在搬运的时候已经设置b.next = a。
这就出现了环,会导致map遍历或者插入一直死循环,导致CPU飙升!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值