JUC LongAdder DoubleAdder LongAccumulator DoubleAccumulator

上一篇博客讲解了java.util.concurrent包中的Striped64这个类,今天讲解LongAdder,DoubleAdder,

LongAccumulator,DoubleAccumulator这四个类,如果读者已经理解了Striped64这个类,今天的内容将变得非常简单,今天讲解的这四个类都继承自Striped64这个类,依托Striped64完成运算.

首先说明下,上篇讲解Striped64这个类的时候只着重讲解了longAccumulate这个方法而没有讲解doubleAccumulate这个方法,这两个方法的原理完全相同,只不过是doubleAccumulate这个方法再做运算的时候需要通过

Double.doubleToRawLongBits 和 Double.longBitsToDouble这两个方法进行转换,其他无任何不同,所以今天也只会讲解LongAdder 和 LongAccumulator这两个类

LongAdder:
LongAdder继承Striped64,最核心的方法已经由Striped64实现,先贴下LongAdder结果核心方法源码:

/**
 * Adds the given value.
 *
 * @param x the value to 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);
    }
}

add(long x)方法是LongAdder中的核心方法

cells和base都来自父类Striped64,如果cells不为null 或者对base进行CAS累加操作失败都会进入if语句块

进入if语句块中将标识字段设置为true(代码没有冲突)

然后再进行判断如果cells数组为null或者cells没有元素或者当前线程hash操作找到对应槽位元素为null或者对当前槽位元素CAS累加有冲突的话直接进入if语句块,调用父类Striped64的longAccumulate方法进行操作,注意传入的LongBinaryOperator为null

/**
 * Equivalent to {@code add(1)}.
 */
public void increment() {
    add(1L);
}

/**
 * Equivalent to {@code add(-1)}.
 */
public void decrement() {
    add(-1L);
}

上面这两个方法比较简单,主要调用add方法进行自增1和自减1操作

/**
 * Returns the current sum.  The returned value is <em>NOT</em> an
 * atomic snapshot; invocation in the absence of concurrent
 * updates returns an accurate result, but concurrent updates that
 * occur while the sum is being calculated might not be
 * incorporated.
 *
 * @return the sum
 */
public long sum() {
    Cell[] as = cells; Cell a;
    long sum = base;
    if (as != null) {
        for (int i = 0; i < as.length; ++i) {
            if ((a = as[i]) != null)
                sum += a.value;
        }
    }
    return sum;
}

sum()方法实现是将base变量的值和所有不为空槽位元素的value进行累加

LongAccumulator实现与LongAdder基本一致,只是可以自定义一个LongBinaryOperator,具体细节大家看下源码很容易理解

    原文作者:JUC
    原文地址: https://blog.csdn.net/liuhongze123/article/details/80108941
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞