回答思路
得分点 原子类、AQS、并发容器 标准回答 Java提供的API中使用CAS的地方有很多,比较典型的使用场景有原子类、AQS、并发容器。 对于原子类,以AtomicInteger为例,它的内部提供了诸多原子操作的方法。如原子替换整数值、增加指定的值、加1,这些方法的底层便是采用操作系统提供的CAS原子指令来实现的。 对于AQS,在向同步队列的尾部追加节点时,它首先会以CAS的方式尝试一次,如果失败则进入自旋状态,并反复以CAS的方式进行尝试。此外,在以共享方式释放同步状态时,它也是以CAS方式对同步状态进行修改的。 对于并发容器,以ConcurrentHashMap为例,它的内部多次使用了CAS操作。在初始化数组时,它会以CAS的方式修改初始化状态,避免多个线程同时进行初始化。在执行put方法初始化头节点时,它会以CAS的方式将初始化好的头节点设置到指定槽的首位,避免多个线程同时设置头节点。在数组扩容时,每个线程会以CAS方式修改任务序列号来争抢扩容任务,避免和其他线程产生冲突。在执行get方法时,它会以CAS的方式获取头指定槽的头节点,避免其他线程同时对头节点做出修改。 加分回答 CAS的实现离不开操作系统原子指令的支持,Java中对原子指令封装的方法集中在Unsafe类中,包括:原子替换引用类型、原子替换int型整数、原子替换long型整数。这些方法都有四个参数:var1、var2、var4、var5,其中var1代表要操作的对象,var2代表要替换的成员变量,var4代表期望的值,var5代表更新的值。 public final native boolean compareAndSwapObject( Object var1, long var2, Object var4, Object var5); public final native boolean compareAndSwapInt( Object var1, long var2, int var4, int var5); public final native boolean compareAndSwapLong( Object var1, long var2, long var4, long var6);