概念

全名: Compare And Swap 比较与交换
无锁算法:基于硬件原语实现,在不使用锁的情况下实现多线程之间的变量同步。
JDK实现:java.util.concurrent包中的原子类(AtomicInteger)就是通过CAS来实现的

步骤

  1. 线程1和线程A将V的副本load到工作内存中;
  2. 假设线程1先到,线程1对比A和V的值:
  • A == V, 直接更新V,此时V变成了1;
  1. 线程2后到,线程2对比A和V的值;
  • A != V, 不能更新V,线程2自旋;
  • 自旋就是一个循坏,重新从主内存中获取V的值然后尝试更新。

image.png

CAS的问题

  1. ABA问题

假设初始值V = 0, A = 0,尝试将V改成1.

V先被改成了1,又被改成了0,此时进行对比的时候,发现V == A仍然成立,那么修改就会成功。但实际上V值是被修改过的。

这就是ABA问题,0 -> 1 -> 0。

解决方案:,
通过添加版本号解决,虽然是0 -> 1 -> 0,但添加版本号以后,变成了A - 0, B - 1, C - 0。前后两次虽然都是0,但因为版本号不同,是可以区分的。目前JDK已经解决了该问题。

  1. 循环时间长,开销大

自旋锁

为什么需要自旋?

因为阻塞和唤醒的开销要比自旋开销大。