简介
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();
}
}