【Java高并发】CAS原理及其优化
一、CAS原理
1.概念
CAS(Compare And Swap):比较并交换。包含3个操作数:
- V:内存位置值
- E:期望值
- N:新值
如果内存位置值与期望值匹配,则将内存位置值更新为新值,否则不作任何操作。
2. JDK具体实现方式及CAS实现原理
见类文件sun.misc.Unsafe中的compareAndSwapXXX方法,通过调用JNI(Java Native Interface)的代码来实现CAS,compareAndSwapXXX方法即借助c语言来调用CPU底层指令来实现。以Intel X86平台来说,最终映射到的CPU指令为"cmpxhg",这是一个原子指令,cpu执行此命令时,实现比较并交换的操作。
对于多核操作系统,cmpxhg指令会给“总线”加锁,只有一个线程会对总线加锁成功,加锁成功之后会执行CAS操作,也就是说CAS的原子性是平台级别的
JDK中的Atomic原子类底层就是使用的无锁化的CAS机制,通过CAS机制保证多线程修改一个值的安全性。
// 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);
二、ABA问题
1. 定义
CAS在操作值的需要检查值有没有发生变化,若没有发生变化则更新,但是若一个值是A,在CAS方法执行之前,被其他线程修改为了B,然后又改回了A,那么CAS方法执行检查时会发现值没有发生变化,但实际上却变化了,即CAS的ABA问题。
public class CASABADemo {
public static AtomicInteger a = new AtomicInteger(1);
public static void main(String[] args) {
Thread main = new Thread(new Runnable() {
public void run() {
System.out.println("操作线程:" + Thread.currentThread().getName() + ", 初始值:" + a.get());
try {
int expectNum = a.get();
int newNum = expectNum + 1;
Thread.sleep(1000);
boolean isCASSuccess = a.compareAndSet</