Java中原子操作

Posted by Clear Blog on May 10, 2016

原子操作避不开谈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更新后的值。