來看看ConcurrentHashMap吧

2021-10-07 16:53:02 字數 2126 閱讀 3807

1. concurrenthashmap中沒有負載因子和閾值嗎

a. 是沒有,改用了sizectl控制,0表示預設值,-1表示正在擴容,>0表示下一次擴容的門檻,-(1+nthreads)n個執行緒正在擴容,sizectl的變化都是cas操作

2. 請講講concurrenthashmap的put操作?

a. 控制key和value都不能為null

b. 再用自旋+cas實現put過程,下面是具體的put

c. 如果桶未初始化就初始化桶

d. 如果桶中還沒有元素就把這個元素插進去,插入這一步就是採用的cas

e. 如果要插入的桶正在擴容遷移元素,就當前執行緒一起幫忙協助擴容

f. 如果桶已經存在且沒有遷移元素

g. 就鎖住這個桶,是採用分段鎖的思想(鎖住後裡面不需要cas)

h. 如果元素存在就替換,不存在size+1,插到鍊錶或者樹的尾部

i. 如果桶的元素個數達到了8就嘗試樹化

j. 元素個數+1(分段鎖思想),同時檢查是否需要擴容

k. 返回

3. 請講講concurrenthashmap的擴容操作?

初始化桶操作:判斷是否正在擴容,正在的話就讓出cpu。否則就用cas更新sizectl(cas控制只有乙個執行緒初始化桶陣列),設定容量,並設定擴容門檻(寫死的)賦值給sizectl

addcount操作,元素數量+1,並會判斷是否需要擴容,這裡是陣列數量採用分段鎖的思想,根據不同執行緒儲存到不同段上

先嘗試把數量加到basecount上,如果失敗再加到分段的countercell上(採用cas新增)

如果不同執行緒對應的分段都新增失敗,就要擴容段

擴容:sizectl儲存著擴容門檻,高位儲存擴容郵戳,低位儲存儲存著擴容執行緒數加1,即(1+nthreads)

sc小於0,說明正在擴容,就當前執行緒加入到遷移元素中去,擴容執行緒+1;

如果沒有執行緒在擴容,自己就擴容,加入遷移元素,sizectl低位為2(1+nthreads)

協助擴容:

執行緒新增元素時發現正在擴容且當前元素所在的桶元素已經遷移完成了,則協助遷移其它桶的元素。遷移完成的標誌:如果桶陣列不為空,並且當前桶第乙個元素為forwardingnode型別,並且nexttab不為空

遷移元素:

擴容時容量變為兩倍,並把部分元素遷移到其它桶中。遷移元素先從靠後的桶開始;遷移完成的桶在裡面放置一forwardingnode型別的元素,標記該桶遷移完成;

過程:遷移元素是用sychronized鎖住該桶,遷移的時候,根據遷移時根據hash&n是否等於0把桶中元素分化成兩個鍊錶或樹;等於0的在原來的位置,不等於0 就在原來的位置+n,(n的擴大的大小)

4. 刪除流程:

a. 刪除元素跟新增元素一樣,都是先找到元素所在的桶,然後採用分段鎖的思想鎖住整個桶,再進行操作。

b. 流程:進入自旋,如果正在擴容,協助擴容,如果沒有,對桶加鎖,找到元素,刪除,如果是樹退化成煉表,還要進行退化操作,刪除了元素,就元素個數-1;返回舊值,沒有刪除元素就返回null

5. 獲取元素:

a. 不加鎖,

b. 所以concurrenthashmap不是強一致性的『

6. jdk1.7和1.8的區別,底層資料結構有什麼不同,put和get操作的不同

a. 資料結構差別:jdk1.7中concurrenthashmap採用了陣列+segment+分段鎖,segment繼承自reentrantlock,缺點:需要兩次hash,hash時間長。優點:併發能力高,segment之間相互不影響;jdk1.8中,陣列+鍊錶+紅黑樹的實現方式來設計,內部大量採用cas操作

b. 資料結構:取消了segment分段鎖的資料結構,取而代之的是陣列+鍊錶+紅黑樹的結構。

c. 保證執行緒安全機制:jdk1.7採用segment的分段鎖機制實現執行緒安全,其中segment繼承自reentrantlock。jdk1.8採用cas+synchronized保證執行緒安全。

d. 鎖的粒度:原來是對需要進行資料操作的segment加鎖,現調整為對每個陣列元素加鎖(node)。

e. 鍊錶轉化為紅黑樹:定位結點的hash演算法簡化會帶來弊端,hash衝突加劇,因此在鍊錶節點數量大於8時,會將鍊錶轉化為紅黑樹進行儲存。

f. 查詢時間複雜度:從原來的遍歷鍊錶o(n),變成遍歷紅黑樹o(logn)。

也來看看智慧型題

1 小明爬樓梯,每次只能爬1層或者2層,問到n層的爬法有多少種?費波拉希數列!2 用1分 2分 5分組成1塊的,多少種組成方法 解 設2分用x個,5分用y個,顯然有2x 5y 100的正整數解就是組成方式 剩下的用1分去填充 得到最後解有51 48 43 38 33 3 46 41 36 31 1 ...

來看看 random state 這個引數

svc random state 0 裡有引數 random state from imblearn.over sampling import smote smote random state 42 裡有引數 random state上面乙個是svd演算法,乙個是處理不平衡資料的smote演算法,我...

回過頭來看看

今天,有個開發姐姐過來討論個問題,關於終端異常宕機的問題,問我有沒有碰到過相似的經歷,我說碰到過2 3次。她說有日誌麼,我搖頭。緊接著,劈頭蓋臉過來,怎麼做的測試啊.日誌可是重要的東西.這玩意兒又很難復現.爾耳。沒等她說完,我就回辦公室了。下午,在與測試組的其他同事一起擼一遍bug的時候,有個bug...