HashMap在并发环境下发生死循环

HashMap不是线程安全的,在高并发的某种情况下会发生死循环,主要是在HashMap扩容时的 transfer方法出现了问题:


/**
     * Transfers all entries from current table to newTable.
     */
    void transfer(Entry[] newTable) {
        Entry[] src = table;
        int newCapacity = newTable.length;
        for (int j = 0; j < src.length; j++) {
            Entry<K,V> e = src[j];
            if (e != null) {
                src[j] = null;
                do {
                    Entry<K,V> next = e.next;//(1)
                    int i = indexFor(e.hash, newCapacity);
                    e.next = newTable[i];
                    newTable[i] = e;
                    e = next;
                } while (e != null);
            }
        }
    }


两个线程P1和P2都走到这个方法,执行方法前链表数据如下:

P1:a->b->c->d->null

P2:a->b->c->d->null

线程按一下顺序执行:

1. P1第一次执行到(1)处时阻塞,此时 next 的值是b ,e的值是a;

2. P2执行完整个流程,此时链表在newTable中可能变成如下情况:

b->a

c

d

3. P1继续执行,以下代码中newTable[i]是P2执行完的链表第一个元素b,执行完以下代码会导致a->b,而在新的一轮循环中,b.next是a,死循环产生;

                    e.next = newTable[i];
                    newTable[i] = e;

死循环产生的必要条件(欢迎指正):

1. 原索引数组的某个链表中的有两个元素A,B相邻

2. A,B被转到新的索引数组的同一个链表,即索引值相同

3. 高并发

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值