CAS:比较并交换
首先介绍一下Unsafe类,它是调用硬件层面的一个原子类,而CAS在该类中则有实现,类中 有使用native修饰的 compareAndSwap 开头的方法,使用的就是CAS技术,该方法调用C++中的cmpxchg的指令,C++的cmpxchg又回去调用CPU的cmpxchg指令,所以CAS是CPU支持的一种指令,CPU会进行判断如果是多核操作情况下还会加上lock指令,lock指令是CPU层面的锁,一般锁的粒度是缓存行级别。
CAS中存在三个值:旧值、新值、版本号 ,其大致的思想类似mysql的行锁,因为同样都是乐观锁思想,使用旧值进行版本号比较,只有版本号一致的情况下才能对共享副本写入新值,否则进行自旋重试,所谓自旋意思是当查到旧值与版本号不一致,则进入自旋状态,底层大致实现就类似于利用死循环,获取失败休眠一段时间进行重试。直到修改成功,所以CAS在并发量大的时候是不推荐使用的。
在AtomicInteger、AtomicLong....类中都有调用到compareAndSwap的方法来实现CAS操作
Unsafe类compareAndSwap开头的方法:
调用C++中的cmpxchg指令
调用CPU的cmpxchg指令
ABA问题
当AB两个线程去读取主内存中的变量进行修改时,A线程去修改主内存的同时B线程也在修改主内存中的共享副本,B线程提交了修改后A线程也提交了修改,覆盖了B线程的操作,产生ABA问题,JDK中提供AtomicStampedReference类来解决ABA问题,使用该类的 compareAndSet方法,修改值的同时指定版本号