1. 程式人生 > 其它 >Java ConcurrentHashMap 底層實現原理

Java ConcurrentHashMap 底層實現原理

JDK 1.8

整體架構

由Node陣列、單向連結串列、紅黑樹組成的,當我們初始化一個ConcurrentHashMap例項的時候,預設會初始化一個長度為16的陣列,由於ConcurrentHashMap它的核心仍然是 雜湊表,所以必然會存在雜湊衝突的情況,所以,ConcurrentHashMap採用拉鍊法來解決雜湊衝突,當雜湊衝突較多的時候,會造成連結串列長度較長的問題,會造成ConcurrentHashMap中一個數組元素的查詢效率降低,因此為了解決這個問題,當陣列長度>64,連結串列長度>8的時候,單向連結串列就會轉化成紅黑樹;另外,一旦紅黑樹的元素個數小於等於6時,紅黑樹就會轉化為單向連結串列
注意:使用treefyBin()

方法將連結串列轉化成紅黑樹

基本功能

ConcurrentHashMap本質上是一個HashMap,但是ConcurrentHashMap在HashMap的基礎上,提供了併發安全的一個實現
如何保證併發安全?主要是通過對Node節點加鎖,來保證資料更新安全的安全性

效能方面的優化

如何在資料安全和併發效能之間做好平衡,在很多地方都有類似的設計,例如:CPU的三級快取、mysql的buffer_pool、synchronized的鎖升級等等
ConcurrentHashMap也做了一個類似的優化
1、JDK 1.8中鎖的粒度是陣列中某一個節點,與JDK 1.7鎖住一個Segment相比,鎖的範圍更小,效能更優
2、在對ConcurrentHashMap執行插入操作時,如果該陣列中的某一節點為空,則進行一個CAS操作完成插入,如果陣列中的某一節點不為空,再對該節點上鎖;在對ConcurrentHashMap執行讀取操作時,由於Node節點的value值和next指標都是用volatile修飾的,保證了可見性,所以讀取資料是不需要上鎖的,每次獲取的都是最新值
3、引入紅黑樹,降低資料查詢的複雜度,紅黑樹的查詢時間複雜度是O(logN)
4、ConcurrentHashMap引入了多執行緒併發擴容的一個實現,多個執行緒對原始陣列進行分片,分片之後,每個執行緒去進行一個分片的資料遷移,從而提升了擴容過程中資料遷移的效率