概念
全名: Compare And Swap 比较与交换
无锁算法:基于硬件原语实现,在不使用锁的情况下实现多线程之间的变量同步。
JDK实现:java.util.concurrent包中的原子类(AtomicInteger)就是通过CAS来实现的
步骤
- 线程1和线程A将V的副本load到工作内存中;
- 假设线程1先到,线程1对比A和V的值:
- A == V, 直接更新V,此时V变成了1;
- 线程2后到,线程2对比A和V的值;
- A != V, 不能更新V,线程2自旋;
- 自旋就是一个循坏,重新从主内存中获取V的值然后尝试更新。
CAS的问题
- 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已经解决了该问题。
- 循环时间长,开销大
自旋锁
为什么需要自旋?
因为阻塞和唤醒的开销要比自旋开销大。