注:文中图片来自《JDK1.7和JDK1.8中HashMap为什么是线程不安全的?》
首先声明一点,在JDK1.7及之前才会发生这种情况。
网上有不少解释,但总感觉缺点儿什么,今天我自己来总结一下。
我们现在看下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, initHashSeedAsNeeded(newCapacity));
table = newTable;
threshold = (int)Math.min(newCapacity * loadFactor, MAXIMUM_CAPACITY + 1);
}
从这里我们可以看到,它是定义了个新的Entry[] newTable,然后通过transfer()方法将table里的数据转移到newTable里,最后将newTable赋给table,那么我们接着来看看transfer()的源码: