CAS


1、含义

CAS(Compare And Swap)包含三个参数 CAS(V, E, N)

  • V:表示要更新的变量;
  • E:表示预期值;
  • N:表示新值。

仅当 V 等于 E 时,才会将 E 更新为 N;如果 V 不等于 E,说明已经有其他线程更新了 V,则当前线程什么也不做。


以上操作表明 CAS 是无锁的,它总是抱着乐观态度,认为自己总是能完成操作。

2、实践

java.util.concurrent.atomic 包下的类,有一组用 CAS 实现的原子操作类。

AtomicInteger 为例:

public class AtomicInteger extends Number implements java.io.Serializable {
    // setup to use Unsafe.compareAndSwapInt for updates
    private static final Unsafe unsafe = Unsafe.getUnsafe();
    private static final long valueOffset;
 
    static {
        try {
            valueOffset = unsafe.objectFieldOffset
                (AtomicInteger.class.getDeclaredField("value"));
        } catch (Exception ex) { 
          throw new Error(ex); 
        }
    }
 
    private volatile int value;
    public final int get() {return value;}
}
  • Unsafe 是 CAS 的核心类,通过 Java 的 native 方法访问。
  • 变量 value 用 volatile 修饰,保证了多线程环境下的可见性。

3、缺点

  • ABA 问题 ``` 问题:如果变量V初次读取的时候是A,并且在准备赋值的时候检查到它仍然是A,那能说明它的值没有被其他线程修改过了吗?

如果在这段期间曾经被改成B,然后又改回A,那CAS操作就会误认为它从来没有被修改过。针对这种情况,java并发包中提供了一个带有标记的原子引用类AtomicStampedReference,它可以通过控制变量值的版本来保证CAS的正确性。 ```

4、参考

面试必问的 CAS ,要多了解