1. 程式人生 > 其它 >LongAdder原始碼閱讀筆記

LongAdder原始碼閱讀筆記

功能描述

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變數失敗後