由于JVM 的 Synchronized 重量级锁涉及操作系统(如Linux)内核态下互斥锁 的使用,因此其线程阻塞和唤醒都涉及进程在用户态到内核态的频繁切换,导致重量级锁开销大、性能低。
而JVM的synchronized轻量级锁 使用CAS(compare and swap , 比较并交换)进行自旋抢锁,CAS 是CPU指令级的原子操作,并处于用户态下,所以JVM轻量级锁的开销较小。
本章首先为大家着重介绍CAS的原理和弊端,然后介绍基于CAS实现的JUC原子类。

1、什么是 CAS

Unsafe 是位于sun.misc包下的一个类,主要提供一些用于执行低级别、不安全的底层操作,如直接访问系统内存资源、自主管理内存资源等。Unsafe大量的方法都是native方法,基于C++语言实现,这些方法在提升Java运行效率、增强Java语言底层资源操作能力方面起到了很大的作用。
Unsafe类的全限定名为sun.misc.Unsafe,从名字中可以看出这个类对普通程序员来说是”危险“的,一般的应用开发都不会涉及此类,Java官方也不建议直接在应用程序中使用这些类。

:::info 说明:为什么此类取名为Unsafe呢? 由于使用Unsafe类可以像 C语言一样使用指针操作内存空间,这无疑增加了指针相关问题,内存泄漏问题出现的概率。总之,在程序中过度使用Unsafe类会使得程序出错的概率变大,使得安全的语言Java 不再安全,因此对于Unsafe的使用一定要慎重。 ::: 原理:
操作系统层面的CAS是一条CPU的原子指令(cmpxchg指令),正是由于该指令具备原子性,因此使用CAS操作数据时不会造成数据不一致的问题,Unsafe提供的CAS方法直接通过native方式(封装C++代码)调用了底层的CPU指令 cmpxchg。所以Java 层面的 CAS 操作是借助于底层CPU原子指令实现。
完成Java应用层的CAS 操作主要涉及Unsafe方法的调用,具体如下:

  1. 获取Unsafe实例。
  2. 调用Unsafe提供的CAS方法,这些方法主要封装了底层CPU的CAS原子指令操作。
  3. 调用Unsafe提供的字段偏移量方法,这些方法用于获取对象中的字段(属性)偏移量,此偏移量值需要作为参数提供给CAS操作。