ConcurrentHashMap1.8原始碼學習之擴容(連結串列結構)
讀原始碼時,transfer(Node<K,V>[] tab, Node<K,V>[] nextTab)方法總是看不懂,咋整呢?畫圖吧,梳理下執行過程。初始容量16,標號為0的槽位下各節點Hash值如下圖,
int n = tab.length
int runBit = fh & n;
Node<K,V> lastRun = f;
如圖,n=16,二進位制位10000,如果fh是10000,那麼runBit=10000&10000(16&16)=10000
第一次執行100000節點;b=0,runBit=10000,b!=runBit為true,runBit=0,lastRun=100000節點。
第二次執行110000節點,b=10000(16),runBit=0,b!=runBit為true。runBit=10000(16),lastRun=110000節點。
第三次執行1100000節點,b=0,runBit=10000(16),b!=runBit為true,runBit=0,lastRun=1100000節點。
第四次執行1110000節點,b=10000(16),runBit=0,b!=runBit為true,runBit=10000(16),lastRun=1110000節點。
結束。
//得到最後一個和前面的節點 高位 不一樣的節點和高位(0或10000)
for (Node<K,V> p = f.next; p != null; p = p.next) {
int b = p.hash & n;
if (b != runBit) {
runBit = b;
lastRun = p;
}
}
//如果最後一個高位不一樣的節點高位是0,則設定低位節點
if (runBit == 0) {
ln = lastRun;
hn = null;
}
//如果最後一個高位不一樣的節點高位是1,則設定高位節點
else {
hn = lastRun;
ln = null;
}
//具體到該例子,hn=1110000,ln=null
//這裡從該槽位的根節點開始
//第一次執行10000&10000(16&16)=10000,走else分支,ln=null,
hn=new Node<K,V>(10000, Node10000.key, Node10000.val, Node1110000);新節點如圖:
//第二次執行100000&10000(32&16)=0,走if分支,
ln=new Node<K,V>(100000, node10000.key, ndoe100000.val, null),新節點如圖:
1100000(96)節點執行後由於最後一個節點和lastRun是同一個節點,故1110000(112)節點不參與執行。
最終hn節點如圖:
Ln節點如圖:
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);
}
//低位節點仍然掛在了新陣列同樣的下標位置,
setTabAt(nextTab, i, ln);
//高位節點掛在了新陣列i+n的位置
setTabAt(nextTab, i + n, hn);
//節點處理完畢
setTabAt(tab, i, fwd);
advance = true;
擴容後節點如圖:
相關文章
- 資料結構學習--連結串列資料結構
- 學習 JavaScript 資料結構(二)——連結串列JavaScript資料結構
- 資料結構之「連結串列」資料結構
- 資料結構之連結串列資料結構
- 012 透過連結串列學習Rust之持久化單連結串列Rust持久化
- 012 通過連結串列學習Rust之持久化單連結串列Rust持久化
- 資料結構之連結串列:206. 反轉連結串列資料結構
- 014 透過連結串列學習Rust之持久化連結串列的DropRust持久化
- 014 通過連結串列學習Rust之持久化連結串列的DropRust持久化
- 資料結構之連結串列【上】資料結構
- 資料結構之單連結串列資料結構
- 資料結構之連結串列操作資料結構
- JAVA資料結構之連結串列Java資料結構
- JavaScript資料結構 之 連結串列JavaScript資料結構
- 資料結構實驗之連結串列二:逆序建立連結串列資料結構
- 資料結構實驗之連結串列九:雙向連結串列資料結構
- 016 透過連結串列學習Rust之安全的雙連結串列佈局Rust
- 016 通過連結串列學習Rust之安全的雙連結串列佈局Rust
- 資料結構實驗之連結串列三:連結串列的逆置資料結構
- 資料結構實驗之連結串列五:單連結串列的拆分資料結構
- 資料結構實驗之連結串列六:有序連結串列的建立資料結構
- 資料結構實驗之連結串列一:順序建立連結串列資料結構
- 資料結構之連結串列篇(單連結串列的常見操作)資料結構
- 資料結構-單連結串列、雙連結串列資料結構
- 資料結構之迴圈連結串列資料結構
- 資料結構之雙向連結串列資料結構
- 【資料結構】連結串列(單連結串列實現+詳解+原碼)資料結構
- 013 透過連結串列學習Rust之實現連結串列的通用函式Rust函式
- 013 通過連結串列學習Rust之實現連結串列的通用函式Rust函式
- Java學習筆記:資料結構之線性表(雙向連結串列)Java筆記資料結構
- 畫江湖之資料結構【第一話:連結串列】單向連結串列資料結構
- 畫江湖之資料結構【第一話:連結串列】雙向連結串列資料結構
- 畫江湖之資料結構 [第一話:連結串列] 單向連結串列資料結構
- 畫江湖之資料結構 [第一話:連結串列] 雙向連結串列資料結構
- 資料結構實驗之連結串列四:有序連結串列的歸併資料結構
- 資料結構與演算法學習-連結串列下資料結構演算法
- 資料結構與演算法學習-連結串列上資料結構演算法
- 單連結串列學習(一)