1 概述
JUC包中提供了一系列基于非阻塞CAS算法的原子操作类,相比于用锁机制具有更好的性能,譬如AtomicLong,AtomicInteger,AtomicBoolean,LongAdder,LongAccumulator等,本文着重介绍一下AtomicLong, LongAdder, LongAccumulator,其类图如下所示
2 AtomicLong
2.1 内部结构
public class AtomicLong extends Number implements java.io.Serializable {
private static final long serialVersionUID = 1927816293512124184L;
// 获得一个unsafe类
private static final Unsafe unsafe = Unsafe.getUnsafe();
//value的偏移量
private static final long valueOffset;
//判断JVM是否支持Long类型无锁CAS
static final boolean VM_SUPPORTS_LONG_CAS = VMSupportsCS8();
private static native boolean VMSupportsCS8();
//获取value变量的偏移量
static {
try {
valueOffset = unsafe.objectFieldOffset
(java.util.concurrent.atomic.AtomicLong.class.getDeclaredField("value"));
} catch (Exception ex) { throw new Error(ex); }
}
//真正的变量值
private volatile long value;
//有参构造器,可以指定初始value值
public AtomicLong(long initialValue) {
value = initialValue;
}
//无参构造器
public AtomicLong() {
}
......
}
2.2 递增与递减方法
incrementAndGet() 原子性递增value的值并返回递增之后的值
decrementAndGet() 原子性递减value的值并返回递减之后的值
getAndIncrement() 原子性递增value的值并返回递增之前的值
getAndDecrement() 原子性递减value的值并返回递减之前的值
以上四个方法底层都是通过调用unsafe的getAndAddLong()来实现,下面来看一下该方法的具体实现:
public final long getAndAddLong(Object var1, long var2, long var4) {
long var6;
do {
//获取原子类中value的值
var6 = this.getLongVolatile(var1, var2);
} while(!this.compareAndSwapLong(var1, var2, var6, var6 + var4));//查看原子类中var2偏移量(value)的值是否是var6,是则将其重新赋值为var6 + var4
return var6;
}
2.3 使用案例
以下是计算两个数之和的代码10000 + 100,使用原子操作类的结果是10100
public class Test {
public static AtomicLong atomicLong = new AtomicLong();
public static void main(String[] args) {
//统计两个数之和
Thread threadone = new Thread(() -> {
for (int