先擼源碼直接了當java
// Original (since JDK1.2) Map methods /** * {@inheritDoc} */ public int size() { long n = sumCount(); return ((n < 0L) ? 0 : (n > (long)Integer.MAX_VALUE) ? Integer.MAX_VALUE : (int)n); }
這裏有個 sumCount()方法 緩存
final long sumCount() { CounterCell[] as = counterCells; CounterCell a; long sum = baseCount; if (as != null) { for (int i = 0; i < as.length; ++i) { if ((a = as[i]) != null) sum += a.value; } } return sum; }
原來看的時候一看見for循環 和 sum+= 就覺得就這樣了。圖樣圖森破!!!!!併發
今天看 LongAdder 發現錯了 。。。高併發
先接着看ConcurrentHashMap 的這個內部類 CounterCell翻譯
/* ---------------- Counter support -------------- */ /** * A padded cell for distributing counts. Adapted from LongAdder * and Striped64. See their internal docs for explanation. */ @sun.misc.Contended static final class CounterCell { volatile long value; CounterCell(long x) { value = x; } }
Cell
類是 Striped64
的靜態內部類。經過註解 @sun.misc.Contended
來自動實現緩存行填充,讓Java編譯器和JRE運行時來決定如何填充。本質上是一個填充了的、提供了CAS更新的volatile變量。code
翻譯下注釋:ip
一種用於分配計數的填充單元。改編自LongAdder和Striped64。請查看他們的內部文檔進行解釋。文檔
LongAdder 和 Striped64 其實都是分片計算部分,簡單理解編譯器
咱們能夠看到Cell類的內部是一個volatile的變量,而後更改這個變量惟一的方式經過cas。咱們能夠猜想到LongAdder的高明之處可能在於將以前單個節點的併發分散到各個節點的,這樣從而提升在高併發時候的效率。源碼
這是Striped64能夠繼續延伸閱讀
http://ifeve.com/java8-striped64-and-longadder/