多線程情況下,HashMap擴(kuò)容可能會形成死循環(huán)情況,或者丟失值。
假設(shè):
三個Entity,rehash后key值分別為3、5、7。
如圖:

init.png
JDK 1.7 HashMap擴(kuò)容時關(guān)鍵代碼:
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; // 第5行 關(guān)鍵步驟1
if (rehash) {
e.hash = null == e.key ? 0 : hash(e.key);
}
int i = indexFor(e.hash, newCapacity);
e.next = newTable[i]; //關(guān)鍵步驟2
newTable[i] = e; //關(guān)鍵步驟3
e = next; //關(guān)鍵步驟4
}
}
}
請記住上面的4個關(guān)鍵步驟?。?!
死循環(huán):
B第一次while循環(huán):

2.png
B第二次while循環(huán):

3.png
B第三次while循環(huán):

4.png
線程B執(zhí)行完的狀態(tài),A恢復(fù)執(zhí)行:

5.png
線程A開始執(zhí)行的狀態(tài):

6.png
線程A開始執(zhí)行第6行,第一次while循環(huán):

7.png
A第二次while循環(huán):

8.png
A第三次while循環(huán):

9.png
線程A執(zhí)行完,已形成死循環(huán)。紅線。
值丟失:
更換下三個Entity的順序,注意如圖:

10.png
線程A開始執(zhí)行:

11.png
線程A第二次while循環(huán):

12.png