简介

CAS是一种用于实现并发编程中线程安全的无锁机制。在 Java 的 java.util.concurrent.atomic 包中得到了完美应用,例如 AtomicInteger。

理念

CAS的核心思想是进行乐观锁操作,在多个线程修改共享变量的时候,它不依赖于传统的锁,而是依靠硬件底层原语直接完成对共享变量的安全更新。它只有在当前变量的值仍为期望值的时候才会更新否则就重试。

工作原理

1️⃣ 三个参数:

CAS 需要以下三个关键参数:

  • 共享变量的当前值 (prev):表示变量的当前状态(例如 balance.get())。
  • 预期值 (expected):表示更新之前,我们认为共享变量应该是什么值。
  • 目标值 (next):表示我们打算写入的新值(更新后的值)。

2️⃣ 操作流程:

假设多个线程都试图将一个变量从手头的 prev 更新为 next 值。CAS 会:

  • 比较共享变量 prev与期望值expected是否相等
  • 如果相等,说明没有其他线程进行修改,CAS会安全地将共享变量更新为next
  • 如果不相等,说明共享变量已经在其他线程中被修改,CAS不会更新该变量,然后会进入重试逻辑。

3️⃣ 结论:
CAS 的操作是原子的,即它由硬件保证在多线程情况下不会被打断。通过 “不断重试” 和 “最终成功” 的方式完成线程安全。

和Synchronized对比

代码示例

https://meowrain.cn/archives/bao-hu-gong-xiang-zi-yuan-dai-ma-shi-xian


class SafeAccountUseAtomicInteger implements Account {
    private AtomicInteger balance;

    public SafeAccountUseAtomicInteger(int balance) {
        this.balance = new AtomicInteger(balance);
    }

    @Override
    public void withdraw(Integer amount) {
        while (true) {
            int prev = balance.get();
            int next = prev - amount;
            if (balance.compareAndSet(prev, next)) {
                break;
            }
        }
    }

    @Override
    public Integer getBalance() {
        return balance.get();
    }
}