【093期】面试官:多线程环境下 HashMap为什么会出现死循环?

本文详细解释了在多线程环境中,HashMap在插入数据时可能出现的死循环现象,主要原因是resize过程中并发操作可能导致哈希链表形成环形,以及如何理解和避免这种问题。作者强调了线程安全性和正确处理并发的重要性。
摘要由CSDN通过智能技术生成

table[bucketIndex] = new Entry<K,V>(hash, key, value, e);

//查看当前的size是否超过了我们设定的阈值threshold,如果超过,需要resize

if (size++ >= threshold)

resize(2 * table.length);

}

如果现在size已经超过了threshold,那么就要进行resize操作,新建一个更大尺寸的hash表,然后把数据从老的Hash表中迁移到新的Hash表中。

调整Hash表大小resize:

void resize(int newCapacity)

{

Entry[] oldTable = table;

int oldCapacity = oldTable.length;

//创建一个新的Hash Table

Entry[] newTable = new Entry[newCapacity];

//将Old Hash Table上的数据迁移到New Hash Table上

transfer(newTable);

table = newTable;

threshold = (int)(newCapacity * loadFactor);

}

当table[]数组容量较小,容易产生哈希碰撞,所以,Hash表的尺寸和容量非常的重要。

一般来说,Hash表这个容器当有数据要插入时,都会检查容量有没有超过设定的thredhold,如果超过,需要增大Hash表的尺寸,这个过程称为resize。

多个线程同时往HashMap添加新元素时,多次resize会有一定概率出现死循环,因为每次resize需要把旧的数据映射到新的哈希表,这一部分代码在HashMap#transfer() 方法,如下:

void transfer(Entry[] newTable)

{

Entry[] src = table;

int newCapacity = newTable.length;

//下面这段代码的意思是:

//  从OldTable里摘一个元素出来,然后放到NewTable中

for (int j = 0; j < src.length; j++) {

Entry<K,V> e = src[j];

if (e != null) {

src[j] = null;

do {

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值