什么是CAS?
- C(Compare) A(and) S(Swap)翻译过来就是比较再交换。
- CAS是一种无锁算法,CAS有3个操作数,1当前值2期望值3需要修改的值,在当前值和期望值相同的时候把当前值更改成为需要修改的值。
- 通俗点说就是:如果想改的值不再是原来的值就结束操作。
CAS在Jdk中的应用
java.util.concurrent.atomic包中的所有类都提供了CAS操作
我们拿AtomicInteger.incrementAndGet()方法来举例,该方法作用是执行value++操作的
可以看到incrementAndGet()方法是通过Unsafe类的getAndAddInt()方法实现的,代码中用到的Unsafe类可以让java操作内存地址,比如通过对象和偏移量直接从内存中获取对应变量的值,Unsafe中的方法是原子操作。unsafe.getAndAddInt()具体实现如下。
//获取内存地址为obj+offset的变量值, 并将该变量值加上delta
public final int getAndAddInt(Object obj, long offset, int delta) {
int v;
do {
//通过对象和偏移量获取变量的值
//由于volatile的修饰,保证了线程的可见性,所有线程看到的v都是一样的
v= this.getIntVolatile(obj, offset);
/*
while中的compareAndSwapInt()方法尝试修改v的值,具体地, 该方法也会通过obj和offset获取变量的值
如果这个值和v不一样, 说明其他线程修改了obj+offset地址处的值, 此时compareAndSwapInt()返回false, 继续循环
如果这个值和v一样, 说明没有其他线程修改obj+offset地址处的值, 此时可以将obj+offset地址处的值改为v+delta, compareAndSwapInt()返回true, 退出循环
Unsafe类中的compareAndSwapInt()方法是原子操作, 所以compareAndSwapInt()修改obj+offset地址处的值的时候不会被其他线程中断
*/
} while(!this.compareAndSwapInt(obj, offset, v, v + delta));
return v;
}
评论区