ConcurrentHashMap原理解析

2021-08-28 06:55:56 字數 1494 閱讀 4953

【什麼是concurrenthashmap?】

眾所周知,hashmap是一種非常高效的資料結構,但是依舊有它的缺陷。那就是在併發插入資料時,有可能會出現帶環鍊錶,讓下一次的讀操作出現死迴圈。於是為了避免hashmap的執行緒安全問題,concurrenthashmap應運而生。

【concurrenthashmap原理】

concurrenthashmap是乙個二級hash表,在乙個總的hash表下面有若干子hash表。

我們將子hash表稱為segment。

那麼採用這種結構有什麼好處呢?

我們知道解決執行緒安全問題的方法,就是加鎖。當時給整體加鎖的話,又會使得效率急劇下降。在concurrenthashmap的結構下我們就可以採用【鎖分段技術】,每個segment就是乙個自治區,讀寫操作高度自治,segment間互不影響。

concurrenthashmap解決執行緒安全問題的具體場景:

場景1:不同segment的讀與讀,讀與寫,寫與寫

可以併發執行

場景2:同一segment的寫與讀

可以併發執行

場景3:同一segment的併發寫入

加鎖因此,採用給單個的segment加鎖,相比於整體加鎖就極大地提高了效率,同時保證了執行緒安全。

【concurrenthash方法】

【get方法】

為輸入的key值,進行hash運算得到hash值

通過hash值定位到對應的segment

再次通過hash值,定位到segment中的對應位置

【put方法】

為輸入的key值,進行hash運算得到hash值

通過hash值定位到對應的segment

為當前segment加可重入鎖

進入segment找到對應位置,進行插入或者覆蓋

釋放可重入鎖

【size方法】

在concurrenthashmap的size方法中採用了樂觀鎖與悲觀鎖相結合的方式。

正常來說,我們統計size時,直接獲取各個segment的子元素的個數之和即可。

當若是當我們剛剛計算結束某一segment的元素之後,該segment又進行了插入或者移除操作怎麼辦呢?

具體實現流程如下:

獲取當前concurrenthashmap的修改次數version

遍歷所有sgement,獲得子元素數量之和

再次獲取當前concurrenthashmap的修改次數version

對比兩次version,如果第二次大於第一次,說明統計過程中有修改,重新統計,嘗試次數+1;若二者相同,說明沒有修改,統計結束。

如果嘗試次數超過閾值,則對每乙個segment加鎖,再重新統計。

再次判斷所有segment的總修改次數是否大於上一次的總修改次數。由於已經加鎖,次數一定和上次相等。

釋放鎖,統計結束

【補充內容】

ConcurrentHashMap原理解析

concurrenthashmap是jdk提供的乙個執行緒安全的集合類,它內部的結構原理和我們常用的hashmap基本是一致,那我們可以先來認識一下hashmap,這樣基本上也能大致明白concurrenthashmap了。hashmap與concurrenthashmap都是用來存放一種鍵值對形式...

ConcurrentHashMap 原理簡要分析

在之前寫過hashtable 與hashmap 兩者之間的異同 通過前面文章,可以知道hashmap 中未進行同步考慮,而 hashtable 則使用了 synchronized 帶來的直接影響就是可選擇,我們可以在單執行緒時使用 hashmap 提高效率,而多執行緒時用 hashtable 來保證...

ConcurrentHashMap 的原理和結構

concurrenthashmap 是乙個高效的執行緒安全的hashmap,它的加鎖機制和hashtable不同,後者用的是低效的synchronized,前者用的是lock。接著前一期的hashmap,先簡單介紹下concurrenthashmap結構,再以它們的主要函式 put 和 get為切入...