在多线程环境下,使用HashMap进行put操作会引起死循环,导致CPU利用率高达100%。
原因:
多线程会导致HashMap的Entry链表形成环形数据结构,一旦形成唤醒数据结构,Entry的next结点永远不为空,
就会产生死循环获取entry。
final HashMap<String,String> map = new HashMap(2);
Thread t = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
new Thread(new Runnable() {
@Override
public void run() {
map.put(UUID.randomUUID().toString(), "");
}
}, "moon" + i).start();
}
}
}, "ftf");
t.start();
t.join();
待补充解释。
---------------------------------解释如下---------------------------------------
解释参考:http://www.importnew.com/26049.html
HashMap在put的时候,插入的元素超过了容量(由负载因子决定)的范围就会触发扩容操作,就是rehash,这个会重新将原数组的内容重新hash到新的扩容数组中,在多线程的环境下,存在同时其他的元素也在进行put操作,如果hash值相同,可能出现同时在同一数组下用链表表示,造成闭环,导致在get时会出现死循环,所以HashMap是线程不安全的。