hashtable 使用一把鎖(鎖住整個鍊錶結構)處理併發問題,多個執行緒競爭一把鎖,容易阻塞;
concurrenthashmap
jdk 1.7 中使用分段鎖(reentrantlock + segment + hashentry),相當於把乙個 hashmap 分成多個段,每段分配一把鎖,這樣支援多執行緒訪問。鎖粒度:基於 segment,包含多個 hashentry。
jdk 1.8 中使用 cas + synchronized + node + 紅黑樹。鎖粒度:node(首結點)(實現 map.entry)。鎖粒度降低了。
jdk 1.7 中,採用分段鎖的機制,實現併發的更新操作,底層採用陣列+鍊錶的儲存結構,包括兩個核心靜態內部類 segment 和 hashentry。
1、segment 繼承 reentrantlock(重入鎖) 用來充當鎖的角色,每個 segment 物件守護每個雜湊對映表的若干個桶;
2、hashentry 用來封裝對映表的鍵-值對;
3、每個桶是由若干個 hashentry 物件鏈結起來的鍊錶
jdk 1.8 中,採用node + cas + synchronized來保證併發安全。取消類 segment,直接用 table 陣列儲存鍵值對;當 hashentry 物件組成的鍊錶長度超過 treeify_threshold 時,鍊錶轉換為紅黑樹,提公升效能。底層變更為陣列 + 鍊錶 + 紅黑樹。
1、粒度降低了;
2、jvm 開發團隊沒有放棄 synchronized,而且基於 jvm 的 synchronized 優化空間更大,更加自然。
3、在大量的資料操作下,對於 jvm 的記憶體壓力,基於 api 的 reentrantlock 會開銷更多的記憶體。
1、重要的常量:
private transient volatile int sizectl; 當為負數時,-1 表示正在初始化,-n 表示 n - 1 個執行緒正在進行擴容;當為 0 時,表示 table 還沒有初始化;當為其他正數時,表示初始化或者下一次進行擴容的大小。
1、資料結構:
node 是儲存結構的基本單元,繼承 hashmap 中的 entry,用於儲存資料;treenode 繼承 node,但是資料結構換成了二叉樹結構,是紅黑樹的儲存結構,用於紅黑樹中儲存資料;treebin 是封裝 treenode 的容器,提供轉換紅黑樹的一些條件和鎖的控制。
3、儲存物件時(put() 方法):
1、如果沒有初始化,就呼叫 inittable() 方法來進行初始化;
2、如果沒有 hash 衝突就直接 cas 無鎖插入;
3、如果需要擴容,就先進行擴容;
4、如果存在 hash 衝突,就加鎖來保證執行緒安全,兩種情況:一種是鍊錶形式就直接遍歷到尾端插入,一種是紅黑樹就按照紅黑樹結構插入;
5、如果該鍊錶的數量大於閥值 8,就要先轉換成紅黑樹的結構,break 再一次進入迴圈
6、如果新增成功就呼叫 addcount() 方法統計 size,並且檢查是否需要擴容。
4、擴容方法 transfer():預設容量為 16,擴容時,容量變為原來的兩倍。
helptransfer():呼叫多個工作執行緒一起幫助進行擴容,這樣的效率就會更高。
5、獲取物件時(get()方法):
1、計算 hash 值,定位到該 table 索引位置,如果是首結點符合就返回;
2、如果遇到擴容時,會呼叫標記正在擴容結點 forwardingnode.find()方法,查詢該結點,匹配就返回;
3、以上都不符合的話,就往下遍歷結點,匹配就返回,否則最後就返回 null。
程式執行時能夠同時更新 conccurenthashmap 且不產生鎖競爭的最大執行緒數。預設為 16,且可以在建構函式中設定。當使用者設定併發度時,concurrenthashmap 會使用大於等於該值的最小2冪指數作為實際併發度(假如使用者設定併發度為17,實際併發度則為32)
關於程式關於世界
首先,在學了1年多的軟體設計的基礎上,問下自己 程式是什麼?業務需求是什麼?程式有什麼用?什麼是演算法?什麼是資料庫?或許每個人的理解不同,會給出不同的答案。那麼自己的理解 程式是乙個讓計算機工作的流程,在程式寫好之後,計算機就會按照,程式設計師定義好流程在執行。其實很多時候,乙個程式的好壞,在於乙...
關於血液關於軟體
1 自然沉降法 將血袋垂直吊掛於4 2 冰箱內,使紅細胞自然下沉1 3d,或將血袋呈70 80 角立於冰箱,需用時,用一次性分漿器分出血漿,制得濃縮紅細胞。2 洗滌法 一般用生理鹽水反覆洗滌3 6次。經洗滌的紅細胞,除白細胞和血小板減少外,血漿蛋白也極少,紅細胞中殘存的血漿蛋白含量約為原總蛋白的1 ...
關於冷漠,關於愛情
我不知道為什麼今天又莫名其妙開始思考愛情這件事,隨之就解決了我一直無法面對冷漠這件事 被冷漠是我始終無法消化的一件事,每當遇見冷漠時,我總會覺得就像一團火把自己燒得面目全非,但對方卻毫無傷害。但我突然懂了,遇到冷漠時,體面的離開即可 在乎你的人一定會在你離開後,找到你跟你解釋為什麼 連解釋都來不及,...