Volatile、CAS、ABA问题

1. volatile

volatile 是 Java 提供的一种轻量级同步机制,主要有两个作用:

保证变量的 可见性:

当一个线程修改了 volatile 变量,其他线程能够立即看到最新的值。

禁止指令重排序:

在 volatile 变量的读写操作前后,JVM 会插入内存屏障,避免指令重排带来的问题。

但是要注意,volatile 不保证原子性,例如 count++ 这种复合操作在多线程下仍然是不安全的。

2、2. CAS(Compare And Swap)

CAS 是一种无锁的原子操作,底层依赖于 CPU 的 cmpxchg 指令来实现。它的逻辑是:
比较某个变量当前的值是否等于预期值(Expected)。
如果相等,就更新为新值(Update)。
如果不相等,说明被其他线程修改过,CAS 操作失败,需要重试。

CAS 的优点:

不需要加锁,线程之间不会阻塞,效率高。

CAS 的缺点:

可能出现 ABA 问题:一个变量从 A → B → A,CAS 检查时发现值还是 A,就会误以为没有变化,导致问题。自旋开销大:CAS 失败会一直自旋重试,如果竞争激烈,会浪费 CPU。只能保证一个变量的原子操作:如果要同时操作多个变量,需要加锁或使用 AtomicReference 等方案。

3、ABA问题

ABA 是 CAS 的典型问题,场景是:

线程 1 读取到变量值为 A。
线程 2 把变量从 A 改成 B,又从 B 改回 A。
线程 1 进行 CAS 时发现值还是 A,以为没变,其实变量已经被改过。

解决 ABA 的办法:

使用 版本号(时间戳)机制:每次更新时不仅更新值,还更新版本号,比如 AtomicStampedReference。使用 AtomicMarkableReference 等带标记的原子类,帮助检测变量是否被修改过。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。