上一篇我们讲解了JDK1.7中的put,get源码,今天我们看看在多线中HashMap造成的如何引起死循环,先来看一下重要源码
代码语言:javascript复制 void transfer(Entry[] newTable, boolean rehash) {
int newCapacity = newTable.length;//新数组的大小
for (Entry<K,V> e : table) {//遍历table 数组
while(null != e) { //遍历数组元素对应的链表
Entry<K,V> next = e.next;
if (rehash) {//是否重新hash
e.hash = null == e.key ? 0 : hash(e.key);
}
//定位数组的下表
int i = indexFor(e.hash, newCapacity);
//这里就是头插法,把当前数据的下一个节点指向新数组的位置即newTable[i]
e.next = newTable[i];
//然后把当前元素复制newTable[i]
newTable[i] = e;
//继续下一个元素
e = next;
}
}
}
JDK1.7在扩容的时候,然后进行数据迁移,使用头插法,最终会导致死循环,首先我们看看什么是头插法,如下图
此时我们在来看看单线程中HashMap如何扩容
在我们了解单线程扩容之后,再来看看多线程如何引起死循环
此时就是JDK1.7多线程导致死循环的过程,认真品其中的过程,可以看到会可能导致数据丢失,下一节我们看JDK1.8源码