您的位置:首页 > 编程语言 > ASP

HaspMap 多线程下 resize 死循环

2013-12-26 17:00 204 查看
HashMap在多线程下面出现死循环,这种情况有点难模拟,千万别在生成环境出现,一旦出现那就等着哭吧。

废话不多说不知道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);
table = newTable;
threshold = (int) (newCapacity * loadFactor);
}


//此方法就是 hashMap 将数据放到新的扩容之后的数组,方法没啥问题,完全正确无误。
void transfer(Entry[] newTable) {
Entry[] src = table;
int newCapacity = newTable.length;
for (int j = 0; j < src.length; j++) {
Entry<K, V> e = src[j];
if (e != null) {
src[j] = null;
do {
//过程(1)
Entry<K, V> next = e.next;
int i = indexFor(e.hash, newCapacity);
e.next = newTable[i];
newTable[i] = e;
e = next;
} while (e != null);
}
}
}


在多线程情况下,情况就不一样了。模拟一种情况:

假设现在HashMap 的table 长度为2 ,因子为1 如下图



现有线程P1 、P2

当P1线程执行到 过程(1)下面的时候

此时 e =a1 ,next = a2 P2 进入执行了并且执行完毕

当前新的结构为



再执行P1 此时得到的新数组索引和P2 是一样。

e.next =newTable[i] 即为 a2 (a2.next =a1)

newTable[i] = e 即为 a1 数组结构变为



e=next 即为 a2

第二次循环的时候

Entry<K, V> next = e.next 即为a1

e.next = newTable[i]; 即为 a1 (a1.next = a2)

newTable[i] = e 即为 a2 数据结构变为



e=next 即为 a1

第三次的循环的时候

Entry<K, V> next = e.next 即为a2

就形成了回环了。

就成了死循环。

在多线程循环下不要使用hashmap 。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: