天天看点

Java并发编程札记-(三)JUC原子类-06JDK1.8新增:LongAdder、DoubleAdder、LongAccumulator、DoubleAccumulator

DoubleAccumulator、LongAccumulator、DoubleAdder、LongAdder是JDK1.8新增的部分,是对AtomicLong等类的改进。比如LongAccumulator与LongAdder在高并发环境下比AtomicLong更高效。本文以LongAdder为例,学习这些类。

API中是这么介绍的:LongAdder中会维护一组(一个或多个)变量,这些变量加起来就是要以原子方式更新的long型变量。当更新方法add(long)在线程间竞争时,该组变量可以动态增长以减缓竞争。方法sum()返回当前在维持总和的变量上的总和。与AtomicLong相比,LongAdder更多地用于收集统计数据,而不是细粒度的同步控制。在低并发环境下,两者性能很相似。但在高并发环境下,LongAdder有着明显更高的吞吐量,但是有着更高的空间复杂度。

outline

//构造函数
LongAdder()
    //创建初始和为零的新加法器。

//方法摘要
void    add(long x)
    //添加给定的值。
void    decrement()
    //相当于add(-1)。
double  doubleValue()
    //在扩展原始转换之后返回sum()as double。
float   floatValue()
    //在扩展原始转换之后返回sum()as float。
void    increment()
    //相当于add(1)。
int intValue()
    //返回sum()作为int一个基本收缩转换之后。
long    longValue()
    //相当于sum()。
void    reset()
    //重置将总和保持为零的变量。
long    sum()
    //返回当前的总和。
long    sumThenReset()
    //等同于sum()后面的效果reset()。
String  toString()
    //返回。的字符串表示形式sum()。
           

例1:使用LongAdder实现long型变量的原子访问和更新

在Java并发编程札记-(三)JUC原子类-02原子方式更新单个变量一文中,例1:long型变量的原子访问和更新使用了AtomicLong实现了原子方式更新long型变量,本文对例子稍作修改。

将计数器类Counter修改为如下

class Counter {
    private static LongAdder counter = new LongAdder();

    public static long addOne() {
        counter.add();
        return counter.sum();
    }
}
           

数次运行例1:long型变量的原子访问和更新中的测试程序,,发现结果全部为计数器值最终值为100。说明说明次计数器在多线程环境下可用,LongAdder实现long型变量的原子访问和更新。

实现原理

与其他原子类一样,LongAdder也是基于CAS实现的。

LongAdder可以代替AtomicLong吗

当然不能。在上面已经提到,与AtomicLong相比,LongAdder更多地用于收集统计数据,而不是细粒度的同步控制。而且,LongAdder只提供了add(long)和decrement()方法,想要使用cas方法还是要选择AtomicLong。

DoubleAdder、LongAccumulator、DoubleAccumulator与LongAdder很相似,就不多做介绍了。

本文就讲到这里,想了解Java并发编程更多内容请参考:

  • Java并发编程札记-目录

END.