0%

CAS及其底层原理

什么是CAS

CAS是比较并交换即CompareAndSwap,是一条CPU并发原语,不能被打断

它会比较主物理内存和当前线程的变量是否相等

如果相等就会改变值,不等就会return false;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import java.util.concurrent.atomic.AtomicInteger;

/**
* @author xixing
* @version 1.0
* @date 2020/7/1 10:23
*
* 1. CAS是什么 ==》CompareAndSwap
* 比较并交换
*/
public class CASDemo {

public static void main(String[] args) {
AtomicInteger atomicInteger=new AtomicInteger(5);

//main thread do something..
System.out.println(atomicInteger.compareAndSet(5,2019)+"\t"+atomicInteger.get());
System.out.println(atomicInteger.compareAndSet(5,1024)+"\t"+atomicInteger.get());
}

}

CAS底层原理

1
2
3
4
5
6
7
8
9
10
11
12
13
public class AtomicInteger extends Number implements java.io.Serializable {
private static final long serialVersionUID = 6214790243416807050L;

// setup to use Unsafe.compareAndSwapInt for updates
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;

static {
try {
valueOffset = unsafe.objectFieldOffset
(AtomicInteger.class.getDeclaredField("value"));
} catch (Exception ex) { throw new Error(ex); }
}

可以看出,AtomicInteger调用了UnSafe类

1
2
3
4
5
6
7
8
/**
* Atomically increments by one the current value.
*
* @return the previous value
*/
public final int getAndIncrement() {
return unsafe.getAndAddInt(this, valueOffset, 1);
}

它的getAndIncrement调用了unsafe的getAndAddInt();

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
*var1 是AtomicInteger本身
*var2 是该对象的内存偏移地址
*var4是要加的值
*var5是找主内存的真实值
*/
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;
}
1
public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);

是一个native类