CAS操作

时间:2025-01-25 16:33:37
    //以原子的方式将实例中的原值加1,返回的是自增前的旧值;
    public final int getAndIncrement() {
        return (this, valueOffset, 1);
    }

    //getAndSet(int newValue):将实例中的值更新为新值,并返回旧值; 、
    public final boolean getAndSet(boolean newValue) {
        boolean prev;
        do {
            prev = get();
        } while (!compareAndSet(prev, newValue));
         return prev;

    }
    //incrementAndGet() :以原子的方式将实例中的原值进行加1操作,并返回最终相加后的结果;
    public final int incrementAndGet() {
        return (this, valueOffset, 1) + 1;

    }

    //addAndGet(int delta) :以原子方式将输入的数值与实例中原本的值相加,并返回最后的结 果;
    public final int addAndGet(int delta) {
        return (this, valueOffset, delta) + delta;
    }

测试

public class AtomicIntegerTest {
    static AtomicInteger sum = new AtomicInteger(0);

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            new Thread(() ->{
                for (int j = 0; j < 10000; j++) {
                    // 原子自增 CAS 
                    ();
                }
            }).start();
        } 
        try {
            (3000);

        } catch (InterruptedException e) {
            ();

        }
        (());
    }
}
incrementAndGet()方法通过CAS自增实现,如果CAS失败,自旋直到成功+1。
public final int incrementAndGet() {
   return (this, valueOffset, 1) + 1;
}
public final int getAndAddInt(Object var1, long var2, int var4) {
    int var5;
    do {
        var5 = (var1, var2);
    } while(!(var1, var2, var5, var5 + var4));

    return var5;
}

CAS缺陷

CAS 虽然高效地解决了原子操作,但是还是存在一些缺陷的,主要表现在三个方面:
  • 自旋 CAS 长时间地不成功,则会给 CPU 带来非常大的开销
  • 只能保证一个共享变量原子操作
  • ABA 问题

ABA问题代码演示

AtomicInteger atomicInteger = new AtomicInteger(1);

new Thread(()->{
    int value = ();
    ("Thread1 read value: " + value);

    // 阻塞1s
    (1000000000L);

    // Thread1通过CAS修改value值为3
    if ((value, 3)) {
        ("Thread1 update from " + value + " to 3");
    } else {
        ("Thread1 update fail!");
    }
},"Thread1").start();

new Thread(()->{
    int value = ();
    ("Thread2 read value: " + value);
    // Thread2通过CAS修改value值为2
    if ((value, 2)) {
        ("Thread2 update from " + value + " to 2");

        // do something
        value = ();
        ("Thread2 read value: " + value);
        // Thread2通过CAS修改value值为1
        if ((value, 1)) {
            ("Thread2 update from " + value + " to 1");
        }
    }
},"Thread2").start();

//[Thread1] DEBUG  - Thread1 read value: 1
//[Thread2] DEBUG  - Thread2 read value: 1
//[Thread2] DEBUG  - Thread2 update from 1 to 2
//[Thread2] DEBUG  - Thread2 read value: 2
//[Thread2] DEBUG  - Thread2 update from 2 to 1
//[Thread1] DEBUG  - Thread1 update from 1 to 3