HashMap死循环问题
HashMap在rehashing的过程中,可能出现死循环问题。
什么是rehashing?
HashMap的初始容量为16,它的最大装载量为12(threshold = capacity * loadFacotry),当第13个key-value插入时,HashMap需要调用resize()方法进行扩容,重新计算原有的key的hash值,然后通过transfer()将所有的key从oldTable分配到newTable。transfer()的源码大概如下:
void transfer(Entry[] newTable) {
Entry[] oldTable = table;
int newCapacity = newTable.length;
for(int i = 0; i < oldTable.length; i++) {
Entry e = oldTable[i];
if(e != null) {
oldTable[i] = null;
}
do { //使用头插入法rehash
int j = indexFor(e.hash, newCapacity);
Entry next = e.next; //A
e.next = newTable[j];
newTable[i] = e;
} while(e != null)
}
}
下面模拟出现死循环的情况:
现在有t1,t2两条线程对map进行rehash:t1执行到A语句时,时间片用完,t2执行。t2完成整个rehash过程。此时t1,t2所对应的map如下:
t2执行完毕,重新执行t1。将k1放入newTable后,再将k2放入newTable,但是由于t2已经将k2.next设置为k1,所以会出现一个死循环问题。