ConcurrentHashMap的原始碼分析

2021-10-10 09:32:34 字數 3188 閱讀 4996

put

final v putval(k key, v value, boolean onlyifabsent) 

//在上一步的else if中 f 不為null時,則判斷f的hash值是否為moved,即-1,如果為-1,表示正在擴容

else if ((fh = f.hash) == moved)

//協助資料遷移

tab = helptransfer(tab, f);

else

break;

}nodepred = e;

//遍歷到最後乙個節點,將新插入的節點賦值給最後乙個節點的next屬性。即新插敘的節點放到了鍊錶尾部。

if ((e = e.next) == null) }}

> 0 鏈轉書操作。 fh小於0,但是不為-1,判斷f是否為樹節點。

//將 k v 組合成乙個node節點,節點中包含hash,key,value,next(null)屬性。

1.castabat(tab, i, null,new node(hash, key, value, null));

2.static final boolean castabat(node tab, int i, nodec, nodev)

解釋:在陣列table的索引i處,如果為null,則設定為node(c)。

初始化

private final node inittable() 

} finally

break;}}

return tab;

}

u.compareandswapint(this, sizectl, sc, -1)
方法解釋:this表示當前物件,sizectl表示sizectl在記憶體的偏移量,說白了就是sizectl在記憶體中的位置,sc就是sizectl的值。

就是說,先根據sizectl找到sizectl的位置,看看sizectl是不是-1,即如果sc == -1,則返回false,sc != -1 ,就把sizectl更改為-1,返回true表示獲取到了初始化的權利。

helptransfer(tab, f);
addcount分兩步:一.數量加1.     二.校驗是否擴容。看**。

private final void addcount(long x, int check) 

//as加1成功,check小於等1,return。

if (check <= 1)

return;

//as加1成功,記錄as的總數。即size的大小

s = sumcount();

}//執行2 //二:校驗是否擴容

if (check >= 0)

//第乙個執行緒開始擴容時執行。將sizectl設定為負數。

else if (u.compareandswapint(this, sizectl, sc,

(rs << resize_stamp_shift) + 2))

transfer(tab, null);

s = sumcount();}}

}

fulladdcount();

private final void fulladdcount(long x, boolean wasuncontended) 

boolean collide = false; // true if last slot nonempty

for (;;)

} finally

if (created)

break;

continue; // slot is now non-empty}}

collide = false;

}else if (!wasuncontended) // cas already known to fail

wasuncontended = true; // continue after rehash

else if (u.compareandswaplong(a, cellvalue, v = a.value, v + x))

break;

else if (countercells != as || n >= ncpu)

collide = false; // at max size or stale

else if (!collide)

collide = true;

else if (cellsbusy == 0 &&

u.compareandswapint(this, cellsbusy, 0, 1))

} finally

collide = false;

continue; // retry with expanded table

}h = threadlocalrandom.advanceprobe(h);

}//初始化countercells,cellsbusy表示cc是否在初始化或擴容,值為0和1.

else if (cellsbusy == 0 && countercells == as &&

u.compareandswapint(this, cellsbusy, 0, 1))

} finally

if (init)

break;

//如果沒有獲取初始化的權利,則嘗試basecount加1,如果失敗,則進行自旋。

else if (u.compareandswaplong(this, basecount, v = basecount, v + x))

break; // fall back on using base}}

ConcurrentHashMap原始碼分析

hashmap 先說hashmap,hashmap是執行緒不安全 的,在併發環境下,可能會形成環狀鍊錶 hashtable hashtable和hashmap的實現原理幾乎一樣,差別無非是1.hashtable不允許key和value為null 2.hashtable是執行緒安全的。但是hashta...

ConcurrentHashMap原始碼詳解

成員變數private static final int maximum capacity 1 30 private static final int default capacity 16 static final int max array size integer.max value 8 pr...

concurrentHashMap原始碼分析

concurrenthashmap是hashmap的執行緒安全版本,內部也是使用 陣列 鍊錶 紅黑樹 的結構來儲存元素。相比於同樣執行緒安全的hashtable來說,效率等各方面都有極大地提高。在這裡可以使用上篇那個 進行測試,根據結果可以知道concurrenthashmap是執行緒安全的,由於分...