Java高併發17-LongAccumulator類詳解

一、LongAccumulator類

1.和LongAdder之間的關係

  • LongAdder類是LongAccumulator的一個特例,我們看一下LongAccumulator的一個構造方法
 public LongAccumlator(LongBinaryOperator accumulatorFunction,long identity) {
  this.function = accumulatorFunction;
  base = this.identity = identity;
 }
  • 其中參數identity是累加器的初始值;參數類型LongBinaryOperator是一種相當於二目運算符的類,它的輸入是兩個Long型數,返回也是一個Long型數字,我們看一下這個接口定義
public interface LongBinaryOperator {
 long applyAsLong(long left,long right);
}
  • 下面來看一下兩個類的等價形式
LongAdder adder = new LongAdder();

LongAccumulator accumulator = new LongAccumulator(new LongBinaryOperator() {
 @Override
 public long applyAsLong(long left,long right) {
  return left + right;
 }
}
  • LongAccumulator相比於LongAdder,可以爲累加器提供非0的初始值,後者只能從0開始累加,並且前者可以自定義累加規則,我們只需要實現這個接口,然後在接口內部的方法內,自定累加規則即可。
  • 從下面的代碼看一下LongAccumulator的accumulate方法和LongAdder類的add方法
//LongAdder的add方法
public void add(long x){
 Cell[] as;
 long b;
 long 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))){
   longAccumulator(x,null,uncontended);
  }
 }
}

//LongAccumulator的accumulate方法
public void accumulate(long x){
  Cell[] as;
 long b;
 long v;
 int m;
 Cell a;
 if(as = cells) != null || r = function.applyAsLong(b = base,x))!= b && !casBase(b,r) {
  boolean uncontended = true;
  if(as == null || (m = as.length -1)<0 || (a = as[getProbe() & m]) == null || !(uncontended = (r = function.applyAsLong(v = a.value,x)) == v|| a.cas(v,r))){
   longAccumulator(x,null,uncontended);
  }
 }
  • 調用casBase的時候後者傳遞的是b+x,前者使用了r=function.applyAsLong(b = base,x)來計算
  • 前者在調用longAccumulator時傳遞的是function,而後者是null,從下面的代碼看出
 else if(casBase(v = base,((fn==null)?v+x:fn.applyAsLong(v,x)))){
  break;
}
  • 當fu爲null時,就是用了x+v的加法運算,這時候等價於LongAdder,當fn不爲null則使用傳遞的fu函數計算

2.總結:可以看到該類提供的功能更加一般化

二、源碼:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章