jdk1.8 hashmap多執行緒put不會造成死迴圈
阿新 • • 發佈:2019-02-06
hashmap多執行緒操作會造成連結串列的迴圈,這個已經被各種部落格的講爛了。大家都知道是put過程中的resize方法在呼叫transfer方法的時候導致的死鎖,故在此不詳述。
今天在看《java高併發程式設計》的時候,書中提到“但是這個(hashmap)死迴圈的問題在jdk8中已經不存在了。由於jdk8對hashmap的內部上線了大規模的調整,因此規避了這個問題”
那麼問題來了- -。jdk8是如何規避這個問題的呢,百度無果,只好自己開啟原始碼看看了。比如知名部落格《Java8系列之重新認識HashMap》,在講述resize的時候還是用了jdk7的程式碼。。。
開啟原始碼 搜尋transfer。。。我的天 居然沒有。。。
那搜尋resize吧。找到核心程式碼如下(忽略紅黑樹部分,僅考慮連結串列部分)
// preserve order Node loHead = null, loTail = null; Node hiHead = null, hiTail = null; Node next; //處理某個hash桶部分 do { next = e.next; {//確定在newTable中的位置 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);
宣告兩對指標,維護兩個連連結串列
依次在末端新增新的元素。(在多執行緒操作的情況下,無非是第二個執行緒重複第一個執行緒一模一樣的操作)
的確沒想到這麼簡單。。。
總結。1.8中hashmap的確不會因為多執行緒put導致死迴圈,但是依然有其他的弊端,比如資料丟失等等。因此多執行緒情況下還是建議使用concurrenthashmap。