Java多线程如何理解CAS:Compare and Set 准则,一文详解!
compareAndSet 的作用是什么?
compareAndSet(expect, update):
如果当前值等于 expect,就把它改成 update,返回 true
否则不改,返回 false
这是 CAS(Compare and Swap)思想的核心。
总结
AtomicInteger 用 CAS 代替锁实现线程安全。
CAS = 比较 + 交换:如果没被别人改过就更新,否则重试。
优点:无锁,性能高(适合高并发)。
缺点:可能自旋多次,导致 CPU 占用高。
疑惑的源代码如下
public int incrementAndGet(AtomicInteger var) {
int prev, next;
do {
prev = var.get();
next = prev + 1;
} while ( ! var.compareAndSet(prev, next));
return next;
}
incrementAndGet() 与 CAS 执行过程详解
我们可以用一个具体的场景,带有多线程干扰的过程,一步一步演示 incrementAndGet() 是如何通过 CAS(Compare-And-Set) 确保线程安全的。
✅ 前提
AtomicInteger var = new AtomicInteger(5);
-
初始值 = 5。
-
当前线程执行
incrementAndGet(var),同时假设 可能有其他线程修改这个值。
✅ 逐步执行过程
Step 1:第一次尝试
prev = var.get(); // prev = 5
next = prev + 1; // next = 6
此时 prev = 5,next = 6。
线程尝试更新:
var.compareAndSet(5, 6)
- 如果成功 → 说明值还没被改过,更新为 6。
- 如果失败 → 说明值被其他线程改了,需要重试。
假设此时另一个线程修改了值
- 其他线程把
var改成 10。
Step 2:compareAndSet 失败
compareAndSet(5, 6)比较当前值和prev:- 当前值 = 10,
prev= 5 → 不相等 → CAS 失败。
- 当前值 = 10,
- 进入
while重新循环。
Step 3:第二次尝试
prev = var.get(); // prev = 10(重新读取当前值)
next = prev + 1; // next = 11
尝试更新:
var.compareAndSet(10, 11)
- 当前值 = 10,
prev= 10 → 相等 → 更新成功。
Step 4:返回结果
- 更新完成,
next = 11,返回 11。
✅ 为什么这样做?
- 即使中间有并发修改,这个循环会一直重试,直到
compareAndSet成功。 - 保证线程安全而且无锁(lock-free)。
✅ 完整执行示例
假设:
- 初始值:
5 - 线程 A 调用
incrementAndGet() - 线程 B 把值改成
10
执行顺序:
A: prev=5, next=6
B: var=10
A: CAS(5,6) 失败
A: prev=10, next=11
A: CAS(10,11) 成功 → 返回11

浙公网安备 33010602011771号