原子操作避不开谈CAS。 先解释下什么是CAS,compareAndSet,见名知意,比较然后设值。 它的核心思想就是cas(v,e,u);v表示要更新的变量,e表示变量的预期值,u表示变量的新值。 当且仅当v的值等于e,才会将v的值更新为u。 否则说明盖值已经被别的线程更改过,当前线程什么都不做,更新失败。 AtomicInteger中是如何如何保证线程安全的加法操作,我们以incrmentAndGet方法为例来说明。
1
2
3
4
5
6
7
8
9
public final int inccrementAndGet(){
for(;;){
int current = get();
int next = current + 1;
if (compareAndSet(current,next)) {//死循环方式直到设值成功
return next;
}
}
}
再看一下Unsafe类中的compareAndSet方法
1
2
3
public final boolean compareAndSet(int expect,int update) {
return unsafe.compareAndSet(this,valueOffset,expect,update);
}
根据下面代码就能看懂this和valueOffset两个字段的含义
1
2
3
4
5
6
7
8
9
10
11
12
private static final Unsafe unsafe = Unsafe.getUnsafe();//Unsafe私有构造方法
private violate int value;//计数器值(原子操作返回值)
private static final long valueOffset;//value属性在对象中的地址偏移量
static {
try{
valueOffset = unsafe.objectFieldOffset
(AtomicInteger.class.getDelaredField("value"));
} catch(Exception e) {
e.printStackTrace();
}
}
现在简单的解释下unsafe.compareAndSet(this,valueOffset,expect,update); this指的是当前调用该方法的AtomicInteger对象,valueOffset就是对象中value的偏移地址, expect是期望值,update更新后的值。