jdk1.7中,resize方法在并发时,有可能将链表变成环,导致程序无止境的循环下去。
导致这种bug的产生原因是,扩容过程采用头插法,会导致链表方向逆向,从而有可以成环
jdk1.8修改了1.7中的倒插法,链表的元素扩容之后,只可能分配到两个地方,1.当前所在的哈希表的下标处,2.当前所在的哈希表的下标处+当前哈希表的容量。
Node<K,V> loHead = null, loTail = null;
Node<K,V> hiHead = null, hiTail = null;
Node<K,V> next;
do {
next = e.next;
if ((e.hash & oldCap) == 0) {
if (loTail == null)
loHead = e;
else
loTail.next = e;
loTail = e;
}
else {
if (hiTail == null)
hiHead = e;
else
hiTail.next = e;
hiTail = e;
}
} while ((e = next) != null);
if (loTail != null) {
loTail.next = null;
newTab[j] = loHead;
}
if (hiTail != null) {
hiTail.next = null;
newTab[j + oldCap] = hiHead;
}
通过(e.hash & oldCap) == 0 判断,然后依次修改链表元素的next,形成两条链表,这个区别于1.7,不会形成链表方向的改变。