設計思路
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和同步包...