API链接:https://docs.oracle.com/javase/8/docs/api/
所在包:java.util.concurrent.atomic
原子操作:不可被中断的一个或一系列操作。在多核处理器上实现原子操作会变得复杂许多。
Java有8种数据类型,并且每个数据类型都有一个包装类,如int和Integer,它们之间的转化也就是我们常称作的自动拆箱和装箱的过程。但是它们只是一个简单的数据,当在并发编程下,没有任何特殊的语义。
volatile能保证可见性,以及阻止编译器和处理器对其重排序,并且对单一数据读写具有原子性,然而对于复合操作却没有原子性,比如i++。
那么如果需要一种原子性int,那就是atomic包下面的AtomicInteger了。
AtomicXXX具体的实现:volatile的基本数据类型+CAS操作。
volatile保证可见性,当一个线程修改volatile变量时,其他线程拿到的都是修改后的最新值。
里面的方法都是对Unsafe方法的封装,而Unsafe里面的方法都是JNI方法,通过调用底层c++方法从而实现指令级的原子操作。
一、原子更新基本类型
使用原子方式更新基本类型,共包括3个类:
AtomicBoolean:原子更新布尔变量
AtomicInteger:原子更新整型变量
AtomicLong:原子更新长整型变量
以AtomicInteger为例解释方法的用处:
构造方法:
public AtomicInteger(int initialValue)
public AtomicInteger()初始值为0
get set方法:
public final int get()
public final void set(int newValue)
public final void lazySet(int newValue){
unsafe.putOrderedInt(this,valueOffset, newValue);
} //没有storeload屏障的set,1.6之后才有
public final int getAndSet(int newValue){
return unsafe.getAndSetInt(this,valueOffset,newValue);
} //获取当前值并set新值
public final boolean compareAndSet(int expect,int update) {
return unsafe.compareAndSwapInt(this,valueOffset, expect, update);
}//比较新值与期望相符则set新值
public final boolean weakCompareAndSet(int expect,int update) {
return unsafe.compareAndSwapInt(this,valueOffset, expect, update);
} //weak的CAS,也就是没有volatile语义的CAS,没有加入内存屏障
加减操作:
public final int getAndIncrement() {
return unsafe.getAndAddInt(this,valueOffset,1);
} //获取当前值并加一
public final int getAndAddInt(Object var1, long var2, int var4) {
int var5;
do {
var5 = this.getIntVolatile(var1,var2);
} while(!this.compareAndSwapInt(var1,var2, var5, var5 + var4));
return var5;
}
public final int getAndDecrement() {
return unsafe.getAndAddInt(this,valueOffset, -1);
} //获取当前值并减一
public final int getAndAdd(int delta) {
return unsafe.getAndAddInt(this,valueOffset, delta);
} //获取当前值并加上差值
public final int incrementAndGet() {
return unsafe.getAndAddInt(this,valueOffset, 1) + 1;
}//加一之后获取当前值
public final int decrementAndGet(){
return unsafe.getAndAddInt(this, valueOffset, -1) - 1;
} //减一之后获取当前值
public final int addAndGet(int delta) {
return unsafe.getAndAddInt(this, valueOffset, delta) + delta;
} //加差值之后获取当前值
阻塞式更新,并且对prev进行一个IntUnaryOperator操作运算:
public final int getAndUpdate(IntUnaryOperator updateFunction){
int prev, next;
do {
prev =get();
next =updateFunction.applyAsInt(prev);
} while(!compareAndSet(prev, next));
return prev;
}
public final int updateAndGet(IntUnaryOperator updateFunction) {
int prev, next;
do{ prev = get();
next=updateFunction.applyAsInt(prev);
} while (!compareAndSet(prev,next));
return next;
}
阻塞式更新,并对prev和x,进行二元运算操作:
public final int getAndAccumulate(int x,IntBinaryOperator accumulatorFunction) {
int prev, next;
do{ prev =get();
next