日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

ConcurrentHashMap的源码分析-高低位原理分析

發(fā)布時(shí)間:2024/4/13 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ConcurrentHashMap的源码分析-高低位原理分析 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

ConcurrentHashMap在做鏈表遷移時(shí),會(huì)用高低位來(lái)實(shí)現(xiàn),這里有兩個(gè)問(wèn)題要分析一下

1. 如何實(shí)現(xiàn)高低位鏈表的區(qū)分

假如我們有這樣一個(gè)隊(duì)列

第14個(gè)槽位插入新節(jié)點(diǎn)之后,鏈表元素個(gè)數(shù)已經(jīng)達(dá)到了8,且數(shù)組長(zhǎng)度為16,優(yōu)先通過(guò)擴(kuò)容來(lái)緩解鏈表過(guò)長(zhǎng)的問(wèn)題,擴(kuò)容這塊的圖解稍后再分析,先分析高低位擴(kuò)容的原理

假如當(dāng)前線程正在處理槽位為14的節(jié)點(diǎn),它是一個(gè)鏈表結(jié)構(gòu),在代碼中,首先定義兩個(gè)變量節(jié)點(diǎn)ln和hn,實(shí)際就是lowNode和HighNode,分別保存hash值的第x位為0和不等于0的節(jié)點(diǎn)

通過(guò)fn&n可以把這個(gè)鏈表中的元素分為兩類,A類是hash值的第X位為0,B類是hash值的第x位為不等于0(至于為什么要這么區(qū)分,稍后分析),并且通過(guò)lastRun記錄最后要處理的節(jié)點(diǎn)。最終要達(dá)到的目的是,A類的鏈表保持位置不動(dòng),B類的鏈表為14+16(擴(kuò)容增加的長(zhǎng)度)=30

我們把14槽位的鏈表單獨(dú)伶出來(lái),我們用藍(lán)色表示?fn&n=0的節(jié)點(diǎn),假如鏈表的分類是這樣

for (Node<K,V> p = f.next; p != null; p = p.next) { int b = p.hash & n;if (b != runBit) { runBit = b; lastRun = p; } }

?通過(guò)上面這段代碼遍歷,會(huì)記錄runBit以及l(fā)astRun,按照上面這個(gè)結(jié)構(gòu),那么runBit應(yīng)該是藍(lán)色節(jié)點(diǎn),lastRun應(yīng)該是第6個(gè)節(jié)點(diǎn)

接著,再通過(guò)這段代碼進(jìn)行遍歷,生成ln鏈以及hn鏈

for (Node<K,V> p = f; p != lastRun; p = p.next) { int ph = p.hash; K pk = p.key; V pv = p.val; if ((ph & n) == 0) ln = new Node<K,V>(ph, pk, pv, ln); else hn = new Node<K,V>(ph, pk, pv, hn); }

接著,通過(guò)CAS操作,把hn鏈放在i+n也就是14+16的位置,ln鏈保持原來(lái)的位置不動(dòng)。并且設(shè)置當(dāng)前節(jié)點(diǎn)為fwd,表示已經(jīng)被當(dāng)前線程遷移完了

setTabAt(nextTab, i, ln); setTabAt(nextTab, i + n, hn); setTabAt(tab, i, fwd);

遷移完成以后的數(shù)據(jù)分布如下

?

總結(jié)

以上是生活随笔為你收集整理的ConcurrentHashMap的源码分析-高低位原理分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。