2 7ConcrruentHashMap和鎖的總結

2021-09-10 15:24:47 字數 2778 閱讀 7497

首先你要知道1.8的hashmap出現紅黑樹。所以在1.8的concurrenthashmap也出現了紅黑樹

1.幾種擴容:

arraylist初始10,1.5倍擴增。grow陣列複製法。

hashmap初始16,2倍擴增,0.75的利用率。index=hash&(length-1)rehashing

hashtable(不常用)初始11,2倍+1擴增,0.75利用率。(奇數)index=hash%length。。rehashing

concurrenthashmap的擴容與hashmap一樣

2.hashtable說說:

陣列+鍊錶的結構

加鎖,synchronized

擴容的說一遍

3.hashmap與hashtable區別:(陣列鍊錶紅黑樹這個大前提不變)

預設容量不同,擴容不同。

因為加鎖造成的效率不同。

執行緒安不安全。

4.concrruenthashmap(jdk1.7還沒紅黑樹)

1.資料結構:segment陣列+hashentry陣列+鍊錶

2.加鎖方式:reentrantlock(可重入and互斥鎖)

value,以及鍊錶都是 volatile 修飾的,保證了獲取時的可見性。

3.put()方法

1.通過競爭獲取鎖,每個segment有自己的鎖

2.通過key定位到segment

3.通過key的hashcode定位到hashentry陣列,值為null則新增,並判斷是否需要擴容。

4.值若不為null,找到的是煉表頭節點,遍歷找到相應的key,覆蓋舊值。

5.解除鎖

注:首先第一步的時候會嘗試獲取鎖,如果獲取失敗肯定就有其他執行緒存在競爭,則利用 自旋獲取鎖。

如果重試的次數達到了 max_scan_retries 則改為阻塞鎖,保證能獲取成功。最後解除當前 segment 的鎖

5.cocurrenthashmap(jdk 1.8)

cas + synchronized(保證原子性)來保證併發安全性。其中的 val next 都用了 volatile 修飾,保證了可見性。

1.get方法:(不需要鎖

根據計算出來的 hashcode 定址,如果就在桶上那麼直接返回值

如果是紅黑樹那就按照樹的方式獲取值

就不滿足那就按照鍊錶的方式遍歷獲取值

2.引入了cas:

借助unsafe類,cas有3個運算元,記憶體值 v、舊的預期值 a、要修改的新值 b。當且僅當預期值 a 和記憶體值 v 相同時,將記憶體值v修改為 b,否則什麼都不做。

3.cas 會出現的問題:aba

解決:對變數增加乙個版本號,每次修改,版本號加 1,比較的時候比較版本號

4.put 過程0.75載入因子(synchronized鎖)

1.根據 key 計算出 hashcode,定位在table中的位置。

2.判斷是否需要對table初始化,如果沒有則初始化陣列。(懶載入方式,第一次插入資料才初始化)

3.通過 key 定位出的 node,如果為空表示當前位置可以寫入資料,利用 cas 嘗試寫入 ,失敗則自旋保證成功

4.如果當前位置不為空,判斷節點型別,如果該節點fh==moved(代表forwardingnode,陣列正在進行擴容)的話,說明正在進行擴容。

5.如果都不滿足,則說明我們找到的是這個煉表頭節點,依次向後遍歷,有key就覆蓋value,沒有鍊錶尾部追加節點(利用 synchronized 鎖寫入資料)

6.如果這個節點的型別是treebin的話,直接呼叫紅黑樹的插入方法進行插入新的節點

7.插入完節點之後再次檢查鍊錶長度 ,如果長度大於8,就把這個鍊錶轉換成紅黑樹;

8.插入完後對當前容量大小進行檢查 ,如果超過了臨界值(實際大小*載入因子)就需要擴容。

5.hashmap的實現原理說一下

hashentry陣列+鍊錶+紅黑樹。key的hashcode定位到陣列,無鍊表則一次定址找到。有鍊錶為了解決雜湊衝突…

6.hashmap的載入因子有什麼用,載入因子為0或1會怎樣

載入因子是表示hsah表中元素的填滿的程度.若:載入因子越大,填滿的元素越多,好處是,空間利用率高了,但:衝突的機會加大了.反之,載入因子越小,填滿的元素越少,好處是:衝突的機會減小了,但:空間浪費多了.儘量減少雜湊衝突。為0浪費記憶體空間,載入因子範圍0.1-1,為1空間利用最大化,雜湊碰撞頻繁。效率低下。

7.hashmap的初始容量為什麼是16,如果初始容量為15或17會怎樣,哪個初始容量的hashmap效能好

16更好,長度16或者其他2的冪,length-1的值為奇數,二進位制的最後一位一定是1,這樣便保證了 h&(length-1) 的最後一位可能為0,也可能為1(這取決於h的值),即與後的結果可能為偶數,也可能為奇數,這樣便可以保證雜湊的均勻性。用16,是為了得到的15二進位制是1111。

而如果 length 為奇數的話,很明顯 length-1 為偶數,它的最後一位是0,這樣 h&(length-1) 的最後一位肯定為0,即只能為偶數,這樣任何hash值都只會被雜湊到陣列的偶數下標位置上,這便浪費了近一半的空間 ,因此,length 取2的整數次冪,是為了使不同 hash 值發生碰撞的概率較小,這樣就能使元素在雜湊表中均勻地雜湊。

27歲以後,27歲之前

27歲之前的人生就是一場充滿了變數冒險和童話故事的荒誕過程,經歷了各種悲慘,痛苦,不可思議的人和事。使得我終於在2013年的這個年頭裡明白了乙個道理 三十而立,誠不欺我。27歲之後的工作,花了2個月的時間揣摩學習頂著可能被炒魷魚的壓力應對著一件一件的事情,可幸27歲之前的人生給了我面對困難挫折壓力的...

27 語言入門 27 成績轉換

描述 輸入乙個百分制的成績m,將其轉換成對應的等級,具體轉換規則如下 90 100為a 80 89為b 70 79為c 60 69為d 0 59為e 輸入 第一行是乙個整數n,表示測試資料的組數 n 10 每組測試資料佔一行,由乙個整數m組成 0 m 100 輸出 對於每組輸入資料,輸出一行。樣例輸...

python2 7換行 Python2 7基礎語法

1.建立檔案xx.py usr bin python3 print hello,world 2.linux下執行 python hello.py 3.編碼 預設字串unicode 設定編碼 coding utf 8 4.識別符號 第乙個字元必須是字母表中字母或下劃線 識別符號的其他的部分有字母 數字...