併發容器ConcorrentHashMap與Hash

Hash是壓縮映射

Hash衝突的處理方式

開放尋址發ThreadLocal

鏈地址法CorrentHashMap

再哈希

 

常用Hash函數

志傑取餘法,乘法取整法,平方取中法

MD5 SHA-1等雖然是加密算法,但其實是摘要算法,不可逆,不可能從摘要反推到明文,彩虹表可以解析,可以加鹽後加密,也可以位運算後加密,或者加密後位運算異或

 

1.7HashMap 死鎖,1..7之前頭插法,多線程同時擴容,一個線程執行一半被掛起,另一個線程擴容完之後,擴容相同的元素,鏈表的next與prev產生了一個循環鏈表頭插死循環,get(不存在元素的時候),循環鏈表造成死循環

concrrentHashMap.putisAbsent()不存在則插入

concrrentHashMap1.7與1.8鎖機制和數據結構有不同,

1.7  segment 用的 reetrantLock,2的平方數,鎖住的桶,無參構造器還是調用的帶參數的內部有參構造,缺省併發大小16,初始化,初始化桶16個segment個,根據加載因子算的,實例化segment[0],segment不可擴容,擴容的是segment下的table

get方法,key拿到hash值,jackwang的hash算法,定位segment,定位table鏈表,get不加所,value是volitail

 

1.7concrrentHashMap

取模a%(2`n) = a&(2`n-1),put方法自旋獲取鎖,自旋一定次數沒拿到,則阻塞拿鎖,put完釋放鎖,頭插法,指針泛化

size()方法是線程安全的可能會影響性能,對segment加鎖再累加計算,containValue也會加鎖,影響性能,

是弱一致的,get並沒有加鎖,返回的可能是過時的數據

 

1.8concrrentHashMap

沒有segment(就是個顯示可重入鎖ReetrantLock),  cas+syc鎖實現, 數組鏈表紅黑樹 ,HashEntry改爲了Node似乎一樣,TreeNode繼承Node,有讀寫鎖機制,當節點數大於8轉換爲紅黑樹,當節點小於6重新轉化爲鏈表,TreeBin是紅黑樹的根節點,ForwordingNode擴容時候用,擴容時標識節點已被移動,sizeClt控制table初始化和擴容操作,-1正在初始化,-N當前有多少個線程正在擴容,0是默認值表明table沒有初始化,正數表示當前table的初始化大小,tabAt()  casTabAt()  setTabAt(),硬件級別的原子操作

new concrrentHashMap()只是簡單的賦值了成員變量,out才實例化table,和1.7不同,1.7做了一系列的初始化操作,1:28

put方法初始化table,初始化大小是2的乘方

get方法,得到hash值,判斷如果是樹,就用樹的方式去找,如果是鏈表就用鏈表的方式去找

put計算hash值,死循環進行插入,key和value都不是null,檢查table是否是空,是空則進行初始化操作,多線程初始化table, 保證只有一個線程在初始化,判斷flag,如果有線程正在初始化進行yield,cas操作保證只有一個線程在初始化,擴容0.75倍位運算,-無符號右移兩位,判斷table頭有沒有值,有值則cas操作放入值,插入時候會看table是否正在擴容,如果橫在擴容則幫助其他線程進行擴容,將table的桶分給其他線程,多個線程之間不操作相同的數據,避免造成1.7get元素之間形成循環鏈表時候死循環的問題,擴容完之後在嘗試向鏈表或者紅黑樹中放入數據,尾插發,放數據時候採用了synchronized鎖,鎖住的是table的表頭,插入時候會看插入後的元素個數是否過了樹的臨界點,過了的話將鏈表轉換爲紅黑樹,map元素累加(cas一次操作basecount,併發累加countCell記錄失敗的次數),判斷是否需要擴容

remove 和put過程很相似,只不過插入變成了刪除,最後map元素個數減1(cas一次操作basecount,併發累加countCell記錄失敗的次數,例如一個線程在put一個線程在remove),6千多行代碼

put和get都會幫助擴容,helperTransfer,兩倍大小的數組,將原來數組的數據移過來,不同的線程步長不同,補貨重複擴容相同的鏈表或者樹,

當對table節點擴容完成標識爲forwordingNode,別的線程就不會再對此線程進行擴容,將新table數組的大小編程當前0.75倍

會幫助一起擴容,避免衝突,採用了步長來分別擴容,分成了多個小任務,每個線程負責其中一個小部分

breeifyBin轉換爲紅黑樹,fh的hash值節點判斷

size方法取總數量時候basecount+countCell ,實際上還是不太準,只是提高了性能,

 

hashTable的方法都加了sychornized關鍵字,鎖了整個對象,強一直性效率低,concrrentHashMap裏了cas與sychornized與分段鎖,提高了效率

數據結構,put get 怎麼實現,sizeCtl控制了初始化大小與擴容大小,Node繼承自Enry用來存儲數據15

concurrentHashMap的數據結構,put與get怎麼實現的,treeNode封裝了我們的節點,treeBin封裝了treeNode並提供了一些鎖的控制

1.7concurrentHashMap併發度是什麼,同時更新map並擴容並不產生鎖競爭的最大線程數的默認爲16,可以在構造函數中設置,會自動調整爲2的正方 1.8中併發度沒有實際意義,如果併發度不夠,則將初始容量提升至併發度大小

數組查找快,擴容麻煩,鏈表添加快,查找慢

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章