多線程情況下乖酬,HashMap擴容可能會形成死循環(huán)情況,或者丟失值忿墅。
假設:
三個Entity扁藕,rehash后key值分別為3、5疚脐、7亿柑。
如圖:
JDK 1.7 HashMap擴容時關鍵代碼:
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行 關鍵步驟1
if (rehash) {
e.hash = null == e.key ? 0 : hash(e.key);
}
int i = indexFor(e.hash, newCapacity);
e.next = newTable[i]; //關鍵步驟2
newTable[i] = e; //關鍵步驟3
e = next; //關鍵步驟4
}
}
}
請記住上面的4個關鍵步驟!9髋望薄!
死循環(huán):
B第一次while循環(huán):
B第二次while循環(huán):
B第三次while循環(huán):
線程B執(zhí)行完的狀態(tài),A恢復執(zhí)行:
線程A開始執(zhí)行的狀態(tài):
線程A開始執(zhí)行第6行呼畸,第一次while循環(huán):
A第二次while循環(huán):
A第三次while循環(huán):
線程A執(zhí)行完痕支,已形成死循環(huán)。紅線蛮原。
值丟失:
更換下三個Entity的順序采转,注意如圖:
線程A開始執(zhí)行:
線程A第二次while循環(huán):