CAS
约 353 字大约 1 分钟
2024-08-08
Java 并发机制实现原子操作有两种: 一种是锁,一种是 CAS
CAS 是 Compare And Swap(比较并替换)的缩写
基本原理:CAS 有 3 个操作数,内存值V,旧的预期值 A,要修改的新值 B。当且仅当预期值 A 和内存值 V 相同时,将内存值 V 修改为 B,否则什么都不做
public static void main(String[] args) {
AtomicInteger atomicInteger = new AtomicInteger(2020);
// 期望、更新
// public final boolean compareAndSet(int expect, int update)
// 如果我期望的值达到了,那么就更新,否则不更新,CAS 是 CPU 的并发原语
atomicInteger.compareAndSet(2020, 2021);
System.out.println(atomicInteger.get());
// false
System.out.println(atomicInteger.compareAndSet(2020, 2021));
// 2021
System.out.println(atomicInteger.get());
}缺点
循环会耗时
一次性只能保证一个共享变量的原子性
ABA问题
ABA 问题
旧预期值被其他线程从 A -> B,再 B -> A,另外个线程的旧预期值是 A
原子引用
带版本号的原子操作可以解决 ABA 问题,对应的 思想:乐观锁
public static void main(String[] args) {
// initialRef 原始值,initialStamp 版本号
AtomicStampedReference<Integer> atomicStampedReference = new AtomicStampedReference(1, 2);
// 获得版本号
atomicStampedReference.getStamp();
// 旧的预期值、新的值、旧版本号、新版本号
atomicStampedReference.compareAndSet(1, 2,
atomicStampedReference.getStamp(), atomicStampedReference.getStamp() + 1);
}上述代码有个坑,因为使用的 Integer,如果超过了 -128 ~ 127 这个范围,他会修改失败,因为值的比较是用的 ==