目錄
1、簡單總結
2、jdk1.7 segments + hashentry陣列 + 鍊錶解析
3、jdk1.8 雜湊表 + 紅黑樹 + cas 解析
參考:如下圖所示,segments繼承了可重入鎖reentrantlock,每個片段有乙個鎖,叫做「分段鎖」。
1).segment(分段鎖)
concurrenthashmap中的分段鎖稱為segment,它即類似於hashmap的結構,即內部擁有乙個entry陣列,陣列中的每個元素又是乙個鍊錶,同時又是乙個reentrantlock(segment繼承了reentrantlock)。
2).內部結構
concurrenthashmap使用分段鎖技術,將資料分成一段一段的儲存,然後給每一段資料配一把鎖,當乙個執行緒占用鎖訪問其中乙個段資料的時候,其他段的資料也能被其他執行緒訪問,能夠實現真正的併發訪問。如下圖是concurrenthashmap的內部結構圖:
從上面的結構我們可以了解到,concurrenthashmap定位乙個元素的過程需要進行兩次hash操作。
第一次hash定位到segment,第二次hash定位到元素所在的鍊錶的頭部。
3).該結構的優劣勢
壞處
這一種結構的帶來的***是hash的過程要比普通的hashmap要長
好處
寫操作的時候可以只對元素所在的segment進行加鎖即可,不會影響到其他的segment,這樣,在最理想的情況下,concurrenthashmap可以最高同時支援segment數量大小的寫操作(剛好這些寫操作都非常平均地分布在所有的segment上)。
所以,通過這一種結構,concurrenthashmap的併發能力可以大大的提高。
參考:
jdk8中concurrenthashmap參考了jdk8 hashmap的實現,採用了陣列+鍊錶+紅黑樹的實現方式來設計,內部大量採用cas操作。
cas:是compare and swap的縮寫,即我們所說的比較交換。cas 操作包含三個運算元 —— 記憶體位置(v)、預期原值(a)和新值(b)。如果記憶體位址裡面的值和a的值是一樣的,那麼就將記憶體裡面的值更新成b。cas是通過無限迴圈來獲取資料的,若果在第一輪迴圈中,a執行緒獲取位址裡面的值被b執行緒修改了,那麼a執行緒需要自旋,到下次迴圈才有可能機會執行。
node:jdk8中徹底放棄了segment轉而採用的是node(儲存key,value及key的hash值的資料結構。其中value和next都用volatile修飾,保證併發的可見性。),其設計思想也不再是jdk1.7中的分段鎖思想。
class nodeimplements map.entry紅黑樹:在jdk8中concurrenthashmap的結構,由於引入了紅黑樹,使得concurrenthashmap的實現非常複雜,我們都知道,紅黑樹是一種效能非常好的二叉查詢樹,其查詢效能為o(logn),但是其實現過程也非常複雜,而且可讀性也非常差。
總結:
jdk1.8版本中synchronized+cas+hashentry+紅黑樹:
azkaban web server原始碼解析
azkaban主要用於hadoop相關job任務的排程,但也可以應用任何需要排程管理的任務,可以完全代替crontab。azkaban主要分為web server 任務上傳,管理,排程 executor server 接受web server的排程指令,進行任務執行 1.資料表 projects 工...
JDK LinkedHashMap原始碼解析
今天來分析一下jdk linkedhashmap的源 public class linkedhashmapextends hashmapimplements map可以看到,linkedhashmap繼承自hashmap,並且也實現了map介面,所以linkedhashmap沿用了hashmap的大...
Redux原始碼createStore解讀常用方法
const store createstore reducer,preloadedstate enhancer 直接返回當前currentstate,獲取state值,return state 我覺得應該深轉殖乙個新的物件返回,不然有可能會被外部修改 function getstate consol...