问题:HashMap扩容死锁

2019-05-11  本文已影响0人  栢鸽

1.8以下的版本才有该问题,在1.8已经解决该问题。

扩容调用transfer

void resize(int newCapacity) {
    Entry[] oldTable = table;
    int oldCapacity = oldTable.length;
    if (oldCapacity == MAXIMUM_CAPACITY) {
        threshold = Integer.MAX_VALUE;
        return;
    }

    Entry[] newTable = new Entry[newCapacity];
    // 下面这行重点
    transfer(newTable, initHashSeedAsNeeded(newCapacity));
    table = newTable;
    threshold = (int)Math.min(newCapacity * loadFactor, MAXIMUM_CAPACITY + 1);
}

transfer方法

/**
 * Transfers all entries from current table to newTable.
 */
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;
            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;
        }
    }
}

我们假设Map中有个table[i]如下链表:

graph TD
A-->B

这个时候有两个个线程要进程扩容分别为T1,T2


image.png
上一篇下一篇

猜你喜欢

热点阅读