HashMap 核心知识点【待整理】

本文探讨了HashMap在使用头插法时如何引发死锁问题。当两个线程同时触发扩容操作,线程B在特定情况下可能导致元素形成环状结构,从而在后续get操作中产生死锁。文章通过分析线程执行步骤,详细解释了死锁产生的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


##

## HashMap的扩容原理


JDK7源码:

```java

为什么头插法会导致死锁?

想要搞明白插入死锁,得先了解扩容:

void resize(int newCapacity) {
     Entry[] oldTable = table; //备份原数组
     int oldCapacity = oldTable.length;
     if (oldCapacity == MAXIMUM_CAPACITY) { //超过int最大值则不扩容
         threshold = Integer.MAX_VALUE;
         return;
    } 
    Entry[] newTable = new Entry[newCapacity]; //创建新数组
    transfer(newTable, initHashSeedAsNeeded(newCapacity)); //将老数组元素迁移到新数组
   table = newTable; //更新table
}
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; //先记下next
            if (rehash) {
                e.hash = null == e.key ? 0 : hash(e.key);
            }
            int i = indexFor(e.hash, newCapacity); //计算新下标
            e.next = newTable[i]; //愿链表成为e的next
            newTable[i] = e; //e成为链表头
            e = next;
        }
    }
}

死锁演示:
初始
在这里插入图片描述
线程A和线程B在put元素时同时触发了扩容,即将各自基于table进行扩容。
当线程B执行完 Entry<K,V> next = e.next; 时,线程A完成了扩容。
我们来分析下线程B接下来会发生什么:

for (Entry<K,V> e : table) { //遍历数组
        while(null != e) { //遍历链表
            Entry<K,V> next = e.next; //先记下next
            if (rehash) {
                e.hash = null == e.key ? 0 : hash(e.key);
            }
            int i = indexFor(e.hash, newCapacity); //计算新下标
            e.next = newTable[i]; //愿链表成为e的next
            newTable[i] = e; //e成为链表头
            e = next;
        }
    }

按transfer()内部逻辑
线程B的第一次while循环:当前e是a,next是b,头插法:a→null
在这里插入图片描述
线程B的第二次while循环:e是b,next是a,头插法:b→a→null
在这里插入图片描述
线程B的第三次while循环:e是a,next是null,头插法:a→b→a→null,形成环,get时会陷入死循环。
在这里插入图片描述
线程B的第四次while循环:e是null,退出。

请介绍下


## 

## ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200908145332836.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zOTIwNzM3NQ==,size_16,color_FFFFFF,t_70#pic_center)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值