Java基础

并发编程(七)CAS

2021-01-13  本文已影响0人  Timmy_zzh

1.CAS

在AQS的加锁和释放锁阶段,多次使用了一种通用操作:compareAndSetXXX.这种操作最终会调用Unsafe中的api进行CAS操作

1.CAS执行过程.png

2.CAS存在的问题

3.CAS实现: ActomicInteger

public class AtomicInteger extends Number implements java.io.Serializable {

    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
    private static final long VALUE;

    static {
        try {
            VALUE = U.objectFieldOffset
                (AtomicInteger.class.getDeclaredField("value"));
        } catch (ReflectiveOperationException e) {
            throw new Error(e);
        }
    }

    private volatile int value;

    public AtomicInteger(int initialValue) {
        value = initialValue;
    }

    public AtomicInteger() {
    }

    public final int get() {
        return value;
    }

    public final void set(int newValue) {
        value = newValue;
    }
    
    public final int getAndSet(int newValue) {
        return U.getAndSetInt(this, VALUE, newValue);
    }

    public final boolean compareAndSet(int expect, int update) {
        return U.compareAndSwapInt(this, VALUE, expect, update);
    }

    public final boolean weakCompareAndSet(int expect, int update) {
        return U.compareAndSwapInt(this, VALUE, expect, update);
    }

    public final int getAndIncrement() {
        return U.getAndAddInt(this, VALUE, 1);
    }

    public final int getAndDecrement() {
        return U.getAndAddInt(this, VALUE, -1);
    }

    public final int getAndAdd(int delta) {
        return U.getAndAddInt(this, VALUE, delta);
    }

    public final int incrementAndGet() {
        return U.getAndAddInt(this, VALUE, 1) + 1;
    }

    public final int decrementAndGet() {
        return U.getAndAddInt(this, VALUE, -1) - 1;
    }

    public final int addAndGet(int delta) {
        return U.getAndAddInt(this, VALUE, delta) + delta;
    }
}
public class AtomicInteger {
    
    public final int getAndIncrement() {
        return U.getAndAddInt(this, VALUE, 1);
    }
}

public final class Unsafe {
    private static final Unsafe theUnsafe;
    
    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 native boolean compareAndSwapInt(Object var1, long var2,
                                                  int var4, int var5);

}
多线程场景下原子操作
  1. 假设线程1和线程2通过getIntVolatile拿到value的值都为1,线程1被挂起,线程2继续执行
  2. 线程2在compareAndSwapInt操作中由于预期值和内存值都为1,因此成功将内存值更新为2
  3. 线程1继续执行,在compareAndSwapInt操作中,预期值为1,而当前的内存值为2,cas操作失败,什么都做,返回false
  4. 线程1重新通过getIntVolatile拿到最新的value值为2,再进行一次compareAndSwapInt操作,这次操作成功,内存值更新为3.
上一篇下一篇

猜你喜欢

热点阅读