CAS 全称为Compare And Swap 翻译为比较交换,作用是让CPU比较两个值是否相等,然后原子的更新某个位置的值,实现方式基于硬件平台的汇编指令,在intel的CPU中,使用的是cmpxchg指令,就是说CAS是靠硬件实现的,从而在硬件层面提升效率。
## CSA 原理
利用CPU的CAS指令,同时借助JNI来完成Java的非阻塞算法。
CAS操作是原子性的,所以多线程并发使用CAS更新数据时,可以不使用锁,JDK中大量使用CAS来更新数据而防止加锁来保持原子更新。
CAS操作包含三个操作数:**内存偏移量位置,预期原值,新值**。如果内存位置的值与预期值相同,那么处理器会自动将该位置值更新为新值,否则处理器不做处理。
## 源码分析
JUC包下面的类大部分都用了CAS实现原子性操作
### AtomicInteger 源码解析
```
// 使用 unsafe 类的原子操作方式
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;
static {
try {
//计算变量 value 在类对象中的偏移量
valueOffset = unsafe.objectFieldOffset(AtomicInteger.class.getDeclaredField("value"));
} catch (Exception ex) { throw new Error(ex); }
}
```
`valueOffset` 字段表示 ` "value"` 内存位置,在 `compareAndSwap` 方法 ,第二个参数会用到.
`偏移量`计算方式=
```
//方法相当于原子性的 ++i
public final int getAndIncrement() {
//三个参数,1、当前的实例 2、value实例变量的偏移量 3、递增的值。
return unsafe.getAndAddInt(this, valueOffset, 1);
}
//方法相当于原子性的 --i
public final int getAndDecrement() {
//三个参数,1、当前的实例 2、value实例变量的偏移量 3、递减的值。
return unsafe.getAndAddInt(this, valueOffset, -1);
}
```
`Unsafe` 调用C 语言可以通过偏移量对变量进行操作
[OpenJDK源码地址](https://download.java.net/openjdk/jdk8/promoted/b132/openjdk-8-src-b132-03_mar_2014.zip/)
目录:`openjdk\jdk\src\share\classes\sun\misc\Unsafe.java`
看代码可知 Unsafe使用了[单例模式](https://www.runoob.com/design-pattern/singleton-pattern.html)并提供getUnsafe()方法获取。
```
//获取Unsafe实例静态方法
@Cal