jdk1.7中HashMap多线程扩容导致查询死循环
原因:
由于jdk1.7中HashMap扩容时迁移数据是采用头插法,顺序会反转
场景:
多线程情况,a,b节点扩容后还是在同一链表中
代码:
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;
}
}
}
图解:
有人向jdk开发者提过这个问题,但是他们并不觉得这是一个bug,HashMap本来就是线程不安全的,在多线程情况下要保证线程安全应该使用ConcurrentHashMap,所以这个问题就是毫无意义的