功能描述
LongAdder通過建立多個副本對象,解決了多線程使用CAS更新同一個對象造成的CPU阻塞,加快了對線程處理的速度。當多個線程同一時刻更新一個AtomicLong類型的變量時,隻有一個線程能夠更新成功,其他線程則更新失敗,繼續嘗試更新。

當使用LongAdder類型的變量時,由于副本數組的存在,線程不一定直接更新變量的本身而是更新副本數組,這樣多線程請求的對象變多了,進而減少了更新時間,當需要使用變量值時,傳回的值是基礎變量的值加上數組内每一個副本的值的和。
源碼解析
LongAdder繼承自Striped64并實作了Serializable接口,而在Striped64類中有一個Cell類
首先分析LongAdder類的add方法
public void add(long x) {
Cell[] as; long b, v; int m; Cell a;
if ((as = cells) != null || !casBase(b = base, b + x)) {
boolean uncontended = true;
if (as == null || (m = as.length - 1) < 0 ||
(a = as[getProbe() & m]) == null ||
!(uncontended = a.cas(v = a.value, v + x)))
longAccumulate(x, null, uncontended);
}
}
從上面的代碼可以看到LongAdder的實作主要依靠的是cells數組,如果cells數組為空的話,則嘗試使用cas更新基礎變量base,如果成功了,則add成功,方法結束,如果cas更新base失敗了,則證明此時有其他線程參與base變量的更新,此後的處理與cells不為空一緻(如果cells不為空,則在此次方法執行前就已經有多線程參與了更新)。
當cells數組不為空或者更新base變量失敗後