这边分析的是JDK1.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; ---------------------(1)
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;
}
}
}
其中关键的地方
next = e.next;
e.next = newTable[i];
newTable[i] = e;
e = next;
线程A和线程B同时触发了扩容,线程B正常完成扩容后,会修改了e.next的引用关系,导致线程A读到错误的引用关系 接着线程A继续执行
|