一、CAS与Volatile的协同工作
1. 原子类中的Volatile变量
以AtomicInteger
为例,其内部通过volatile
变量保证值的可见性,结合CAS实现原子更新:
public class AtomicInteger {
private volatile int value; // 核心存储
public final int get() {
return value; // 直接读取volatile变量
}
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
}
2. 协作优势
- Volatile:确保每次CAS操作前能读取到最新值。
- CAS:在最新值的基础上安全更新,避免多线程冲突。
二、CAS的ABA问题
1. ABA问题描述
- 场景:线程A读取变量值为
A
,线程B将其改为B
后又改回A
,线程A的CAS操作仍成功。 - 隐患:数据逻辑状态已变化,但CAS无法感知中间状态。
2. 解决方案:AtomicStampedReference
通过引入版本号标记变量的修改历史:
AtomicStampedReference<String> ref = new AtomicStampedReference<>("A", 0);
// 线程A尝试修改
int[] stampHolder = new int[1];
String current = ref.get(stampHolder); // 获取值和版本号
ref.compareAndSet(current, "B", stampHolder[0], stampHolder[0] + 1);