标准答案
- CAS 需要比较旧值,成功时写入新值;失败时通常重读并重试。
- ABA 指值从 A 变 B 又回到 A,单纯比较值无法发现中间变化,可用版本号或带标记引用。
- 高竞争、长临界区或失败代价高时,自旋会浪费 CPU,应使用锁、队列或退避。
- CAS 只适合能被单次原子更新表达的不变式,多个字段仍需更高层同步。
题目解析
CAS 适合把一个短小状态转换表达成比较并交换;失败时通常重读并重试。高竞争下失败率升高,线程会消耗 CPU,却未必比阻塞锁更快。
ABA 会让值从 A 变 B 再回到 A,单纯比较值看不出中间变化。涉及节点生命周期或版本语义时,要使用版本号、标记引用或更高层同步。
自旋只适合预计很快释放的竞争。临界区长、线程多、CPU 已饱和或失败代价高时,应使用锁、队列、退避或限次重试。
常见误区
- 误区:CAS 永远比锁快。改正:比较失败率、自旋时间、上下文切换和实际尾延迟。
- 误区:忽略 ABA。改正:需要检测中间变化时引入版本或带标记的引用。
- 误区:在高竞争下无限循环重试。改正:设置退避和上限,必要时退回阻塞同步或队列。