1、CAS 通过硬件保证比较-更新的原子性,不涉及用户态内核态的切换。
2、CAS 是 CPU 的原子指令(cmpxchg指令),不会造成数据的不一致问题。Unsafe提供的 CAS 方法底层实现的是 CPU 指令cmpxchg。
3、执行cmpxchg指令,会判断 当前系统是否为多核系统,如果是给总线加锁,只有一个线程给总线加锁成功,加锁成功后执行 CAS,也就是说 CAS 原子性实际上是 CPU 实现独占的,比起synchronized重量级锁,这里排他时间要短很多,多线程情况下,性能要好很多。
4、Java 中的 CAS 操作依赖于Unsafe方法,Unsafe类中所有的方法都是native修饰的,Unsafe的方法直接调用操作系统底层资源。
5、valueOffset表示变量值在内存中偏移地址,Unsafe是根据内存偏移地址获取数据。
6、CAS 并发原语体现在 Java 的Unsafe的各个方法,调用Unsafe的各个方法,JVM 会帮我们实现CAS汇编指令,这完全依赖于硬件来实现原子操作,由于 CAS 是一种系统原语,是由若干条指令组成,用于完成某个功能的一个过程,原语执行是连续的,不允许中断,CAS 是一条 CPU 原子指令,不会造成数据的不一致问题。
public final int getAndIncrement() {return unsafe.getAndAddInt(this, valueOffset, 1);
}public final int getAndAddInt(Object var1, long var2, int var4) {int var5;do {var5 = this.getIntVolatile(var1, var2);} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));return var5;
}
自旋锁:
CAS是实现自旋锁的基础,CAS 利用 CPU 指令保证操作的原子性,以达到锁的效果,至于自旋,是指尝试获取锁的线程不会立即阻塞,而是采用循环的方式去尝试获取锁,当线程发现锁被占用,会不断判断锁的状态,直到获取,这样的好处可以减少上下文切换的消耗,缺点就是循环消耗 CPU。