深入理解CAS
大约 1 分钟JavaJUC并发编程
什么是CAS
atomicInteger.compareAndSet() 比较并更新。如果期望的值达到了,那么就更新,否则不更新。
/**
* Atomically sets the value to the given updated value
* if the current value {@code ==} the expected value.
*
* @param expect the expected value
* @param update the new value
* @return {@code true} if successful. False return indicates that
* the actual value was not equal to the expected value.
*/
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
代码实践
public class CasDemo {
public static void main(String[] args) {
AtomicInteger atomicInteger = new AtomicInteger(2021);
// 如果期望的值达到了,那么就更新,否则不更新
System.out.println(atomicInteger.compareAndSet(2021, 2022));
atomicInteger.compareAndSet(2021, 2022);
System.out.println(atomicInteger.get());
System.out.println(atomicInteger.compareAndSet(2021, 2022));
System.out.println(atomicInteger.get());
}
}
结果:
true
2022
false
2022
Process finished with exit code 0
CAS是CPU的并发原语。
AtomicInteger加1的原理
AtomicInteger atomicInteger = new AtomicInteger(2021);
atomicInteger.getAndIncrement();

Java无法操作内存,Java可以调用C++(native),C++可以操作内存。Unsafe类相当于Java的后门,可以通过这个类操作内存。

Unsafe类里的getAndAddInt方法

// AtomicInteger类
public final int getAndIncrement() {
return unsafe.getAndAddInt(this, valueOffset, 1);
}
// UnSafe类
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;
}
var1相当于数组对象a,var2相当于a中的角标i,因为var5==a[i] ,var5+1就是a[i]+1,即实现了getAndIncrement()。
总结
比较当前工作内存中的值和主内存中的值,如果这个值是期望的,那么则执行操作。否则不执行。如果不是就一直循环。
缺点
- 循环会耗时。
- 一次性只能保证一个共享变量的原子性。
- 存在ABA问题。