目录
一.什么是CAS
二.流程
三.缺点
四.ABA 问题
五.解决ABA问题
一.什么是CAS
CAS(Compare And Swap,比较并交换),通常指的是这样一种原子操作:针对一个变量,首先比较它的内存值与某个期望值是否相同,如果相同,就给它赋一个新值。
- CAS是一个不可分割的原子操作,并且其原子性是直接在硬件层面得到保障的。
- CAS是乐观锁的一种实现方式,Java原子类中的递增操作就通过CAS自旋实现的。
- CAS是一种无锁算法,在不使用锁(没有线程被阻塞)的情况下实现多线程之间的变量同步。
二.流程
三.缺点
CAS 虽然高效地解决了原子操作,但是还是存在一些缺陷的,主要表现在三个方面:
- 自旋 CAS 长时间地不成功,则会给 CPU 带来非常大的开销
- 只能保证一个共享变量原子操作
- ABA 问题
四.ABA 问题
CAS算法实现一个重要前提需要取出内存中某时刻的数据,而在下一时刻比较并替换,那么在这个时间差里数据可能会发生的变化。比如,当有多个线程对一个原子类进行操作的时候,某个线程在短时间内将原子类的值A修改为B,又马上将其修改为A,此时其他线程不感知,还是会修改成功。
五.解决ABA问题
数据库有个锁称为乐观锁,是一种基于数据版本实现数据同步的机制,每次修改一次数据,版本就会进行累加。
同样,Java也提供了相应的原子引用类AtomicStampedReference。
public class AtomicStampedReference<V> {
private static class Pair<T> {
final T reference;
final int stamp;
private Pair(T reference, int stamp) {
this.reference = reference;
this.stamp = stamp;
}
static <T> Pair<T> of(T reference, int stamp) {//stamp参数
return new Pair<T>(reference, stamp);
}
}
...
}
stamp是版本参数,在开发中每次修改变量时可以通过+1保证版本唯一性。这样就可以保证每次修改后的版本也会往上递增。这就解决了ABA问题。