P說 多執行緒HashMap產生死迴圈

2021-10-06 08:19:18 字數 1902 閱讀 6387

在1.7及以前,使用hashmap進行put操作時,當元素超過閾值時,會觸發resize操作,這時候可能就會出現死迴圈的情況,導致cpu佔用率達到100%。

首先,我們要先了解hashmap的資料結構,hashmap的主幹是乙個entry陣列。entry是hashmap的基本組成單元,每乙個entry包含乙個key-value鍵值對。(其實就是乙個陣列,陣列儲存著單向鍊錶的表頭)

當存在hash衝突時,就會把新元素加入到鍊錶中,而這一步就是出現死迴圈的關鍵,jdk 1.7及以前,會被新元素插入到頭部,因此才可能產生死迴圈。

由於死迴圈是在進行put操作時產生的,所以先看put方法。

public v put

(k key, v value)

} modcount++

;//該key不存在,需要增加乙個結點

addentry

(hash, key, value, i)

;return null;

}

當要新增乙個新的節點時,就會去判斷是否超過閾值,也就是在addentry中。

void

addentry

(int hash, k key, v value,

int bucketindex)

resize時,會把table(陣列)空間擴大一倍,因為陣列變大,hash值計算會有所不同,所以原本的資料要進行轉移,重新hash。

void

resize

(int newcapacity)

transfer方法就是出現問題的關鍵位置。

void

transfer

(entry[

] newtable)

while

(e != null);}

}}

正常情況下,這段**是不會出錯的。

而執行緒b在獲得cpu使用權之後,執行完了一整個流程**,所以此時hashmap中的陣列及鍊錶結構如下,看清楚圖中紅色部分,也就是說執行緒a中的e仍然指向key:3next仍然指向key:7

此時,執行緒a被排程回來執行。

do

while

(e != null)

;

執行e.next = newtable[i];,因為e為key:3,此時newtable[i]key:7,因此key:3會指向key:7,如圖所示。

執行newtable[i] = e,陣列3會指向key:3

那麼這是,環形已經形成。

執行e = next;永遠會在key:3key:7中迴圈。

HashMap多執行緒下發生死迴圈的原因

由於在公司專案中偶爾會遇到hashmap死迴圈造成cpu100 重啟後問題消失,隔一段時間又會反覆出現。今天在這裡來仔細剖析下多執行緒情況下hashmap所帶來的問題 1 多執行緒put操作後,get操作導致死迴圈。2 多執行緒put非null元素後,get操作得到null值。3 多執行緒put操作...

HashMap 多執行緒 死迴圈 Java

hashmap,眾所周知,是執行緒不安全的。在多執行緒的情況下,在get 非常有可能出現死迴圈。因為 hashmap採用鍊錶解決hash衝突,因為是鍊錶結構,那麼就很容易形成閉合的鏈路,這樣在迴圈的時候只要有執行緒對這個hashmap進行get操作就會產生死迴圈。只 有乙個執行緒對hashmap的資...

多執行緒併發產生的原因

背景 先看下面一段 看看執行結果 class program public class accounttest 有乙個accounttest類,類裡面有乙個account值,有乙個add方法功能是把account值累加100萬次 main方法裡面開啟了兩個任務,兩個任務共用乙個accounttest...