CAS是什么
CAS是java利用unsafe类通过对计算机底层的调用来进行数据的操作。底层实现为自旋锁。
测试
public class CASDemo {
public static void main(String[] args) {
AtomicInteger atomicInteger = new AtomicInteger(2020);
// public final boolean compareAndSet(int expect, int update)
// 如果期望的值达到了,那么就更新,否则,就不更新,CAS 是 CPU 的并发原型
System.out.println(atomicInteger.compareAndSet(2020, 2021));
System.out.println(atomicInteger.get());
System.out.println(atomicInteger.compareAndSet(2021, 2020));
System.out.println(atomicInteger.get());
System.out.println(atomicInteger.compareAndSet(2020, 6666));
System.out.println(atomicInteger.get());
}
}
结果输出
利用CAS解决ABA问题
CAS对数据修改时,可能会出现对数据修改两次,修改后值与之前相同的情况,因此会认定为未修改,此类问题被称为ABA问题,为了解决此类问题可以使用乐观锁,对每次记录新增一个记录,每次修改记录+1。
测试
public class CASDemo {
public static void main(String[] args) {
AtomicStampedReference<Integer> atomicStampedReference = new AtomicStampedReference<>(1,1);
new Thread(()->{
int stamp = atomicStampedReference.getStamp(); //获得版本号
System.out.println("a1 =>"+atomicStampedReference.getStamp());
System.out.println(atomicStampedReference.compareAndSet(1, 2, atomicStampedReference.getStamp(), atomicStampedReference.getStamp() + 1));
System.out.println("a2 =>"+atomicStampedReference.getStamp());
System.out.println(atomicStampedReference.compareAndSet(2, 1, atomicStampedReference.getStamp(), atomicStampedReference.getStamp() + 1));
System.out.println("a3 =>"+atomicStampedReference.getStamp());
},"a").start();
new Thread(()->{
int stamp = atomicStampedReference.getStamp(); //获得版本号
System.out.println("b1 =>"+stamp);
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(atomicStampedReference.compareAndSet(1, 6, atomicStampedReference.getStamp(), atomicStampedReference.getStamp() + 1));
System.out.println("b2 =>"+atomicStampedReference.getStamp());
},"b").start();
}
}
输出结果