CAS学习记录
CAS 概述
CAS(Compare And Swap,比较并交换)是并发编程中一种无锁同步机制,它通过硬件层面的原子操作保证多线程环境下变量更新的安全性,避免了传统锁(如 synchronized)带来的线程上下文切换开销,是实现乐观锁的核心技术。
有三个核心参数:
- 内存地址 V:存储要操作的变量的内存位置
- 预期值:线程认为当前内存地址 V 中应该存储的值
- 新值:线程希望将内存地址 V 更新为的值
当且仅当内存地址 V 中的实际值等于预期值 A 时,才将 V 的值更新为 B;否则不做任何操作。保证了原子性。
执行流程
当多线程修改一个共享变量 count 时,假设初始值为 10:
- 线程 1 读取 count 的值,记录预期值为 A,计划将其更新为新值 B=11;
- 线程 1 执行 CAS 操作:检查 count 的实际值是否等于 A(10);
- 若相等:则将 count 更新为 B(11),操作成功
- 若不相等:说明 count 被其它线程修改过,则不更新,操作失败
- 若操作失败,线程可以选择重新读取新值,再次尝试 CAS 或放弃。
底层实现
CAS 的原子性依赖于 CPU 硬件指令,这些指令由 CPU 直接支持,确保比较和交换操作在一个不可分割的步骤中完成,因此无需使用锁就能保证线程安全。
优缺点
优点
- 无锁开销:避免了线程阻塞导致的上下文切换和调度开销
缺点
- ABA 问题:变量的值从 A 被改为 B,再改回 A,CAS 会认为值未变(因为预期值 A 与实际值 A 相等),但实际已发生过修改,可能导致逻辑错误。
解决方案:引入版本号,跟踪变量的修改次数。每次更新时不仅比较值,还比较版本号(戳记),确保 “值 + 版本” 均匹配才更新。
- 循环重试开销,若并发冲突频繁(如大量线程同时修改同一变量),CAS 会不断失败并重试,导致线程长时间占用 CPU,反而降低性能。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Myskill-blog!