1. 程式人生 > >jdk1.8 hashmap多執行緒put不會造成死迴圈

jdk1.8 hashmap多執行緒put不會造成死迴圈

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。