ConCurrentHashMap的實現原理

2021-08-20 09:45:53 字數 1133 閱讀 7275

設計思路

concurrenthashmap採用分段鎖的思想,每乙個段都有一把鎖,從而提高了併發度(即同時操作concurrenthashmap而不產生鎖競爭的執行緒最大數)。另外,當設定併發數時,會預設將併發數改為2的冪。

所謂的段,就是segment,他和hashmap的結構很像,都在內部有乙個entry陣列,並且繼承了重入鎖,用於對段的上鎖。

分段建立

jdk1.6會在一開始就建立所有的segment,而jdk1.7除了第乙個segment,其餘的segment都是在put時,動態建立的,所以,在每一次查詢段的時候,都會判斷段是否為空,如果為空則建立。由於ensuresegment方法要在併發場景被呼叫,所以建立段時,通過cas演算法實現,**如下:

if ((seg = (segment)unsafe.getobjectvolatile(ss, u))

== null)

}

put方法

與jdk1.6不同的是,jdk1.7在put時,會用trylock(),其餘並無不同。

put時,先通過key找到對應的段,在找到段內的entry,段內操作和hashmap類似。

get方法和containskey方法

由於concurrenthashmap的get方法和containskey都是不加鎖的,所以很有可能當concurrenthashmap遍歷過程中有其他的執行緒對其內容進行更改,導致兩方法返回的資料不是最新的資料。

size方法

size方法也會使用cas對modcount進行判斷,當多次重試後,會對所有的segment上鎖。

concurrenthashmap不允許key和value為空

設計思路

jdk1.8取消了segment的概念,還是使用的hashmap中陣列加鍊表的資料結構,但是對於每乙個陣列進行加鎖,以調整鎖的粒度。同時,為了防止hash衝突造成的鍊錶過長,當鍊表長度大於8時,會把鍊錶變為紅黑二叉樹的資料結構,當紅黑樹的長度小於等於6時,又可以轉化為鍊錶。

使用了synchronized關鍵字而不是重入鎖

可見jdk1.8對synchronized進行了效能優化。

ConcurrentHashMap實現原理

concurrenthashmap實現原理 在jdk1.7中 concurrenthashmap是通過segment陣列 hashentry陣列 單鏈表的結構進行儲存資料。segment陣列中存放的是hashentry陣列的首位址,hashentry中存放的是乙個單鏈表 首節點位址 put 我們通過...

ConcurrentHashMap 實現原理

由於hashmap是乙個執行緒不安全的容器,主要體現在容量大於總量 負載因子發生擴容時會出現環形鍊錶從而導致死迴圈。因此需要支援執行緒安全的併發容器concurrenthashmap。如圖所示,是由segment陣列 hashentry陣列組成,和hashmap一樣,仍然是陣列加鍊表組成。concu...

ConcurrentHashMap儲存原理

concurrenthashmap是併發雜湊對映表的實現,它允許多執行緒環境完全併發讀取,並且支援16個執行緒併發更新。相對於hashtable和同步包包裝的hashmap collections.synchronizedmap new hashmap 具有更高的併發性。在hashtable和同步包...