死循环
HashMap扩容过程
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);
table = newTable;
threshold = (int)(newCapacity * loadFactor);
}
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;
int i = indexFor(e.hash, newCapacity);
e.next = newTable[i];
newTable[i] = e;
e = next;
} while (e != null);
}
}
}
初始情况
两个线程,线程A和线程B,当执行到transfer()方法中src[j] = null;时,线程A切换,那么对于线程A而言,是这样的
当B线程完成扩容时,是这样的
此时A线程开始扩容
因为e=3,在B线程扩容完之后e.next=null;所以变成下图
之后元素7,在B线程扩容完之后7.next=3,
由于现在3.next!=null循环继续
死循环来了
元素丢失
正常扩容
多线程,某个线程先放7,7.next=null
再放5,5.next=null;循环结束,元素3就不见了