JUC并发编程学习笔记(十八)深入理解CAS

深入理解CAS

什么是CAS

为什么要学CAS:大厂你必须深入研究底层!有所突破!

java层面的cas------->compareAndSet

compareAndSet(int expectedValue, int newValue) 期望并更新,达到期望值就更新、否则就不更新!

package org.example.cas;
import java.util.concurrent.atomic.AtomicInteger;
public class CASDemo {
public static void main(String[] args) {
AtomicInteger atomicInteger = new AtomicInteger(2020);
//JAVA CAS -> 比较并交换
//期望、更新
//compareAndSet(int expectedValue, int newValue)
//如果我期望的值达到了那么就跟新、否则就不更新;CAS 是CPU的并发原语!
System.out.println(atomicInteger.compareAndSet(2020, 2021));
//达到期望值更新成功
System.out.println(atomicInteger.get());
//更新后未达到期望值,更新失败
System.out.println(atomicInteger.compareAndSet(2020, 2021));
System.out.println(atomicInteger.get());
}
}

Unsafe类

java不能直接操作内存,但是可以调用c++,c++可以操作内存,java可以通过native关键字定义的方法来调用c++。Unsafe类就像是java留给自己的一个后门。所以Unsafe类中都是native方法和调用native方法的方法!

在原子类里,有一个getAndIncrement方法用作自增、那么他的底层是如何实现的呢?

其实就是调用的unsafe类中的getAndAddInt方法

public final int getAndIncrement() {
//dalta传入了1
return U.getAndAddInt(this, VALUE, 1);
}
public final int getAndAddInt(Object o, long offset, int delta) {
int v;
do {
//v每次都跟新为最新值,所以一直会是期望的值!就执行了++的操作
v = getIntVolatile(o, offset);
//如果当前对象o期望的值等于v,那么将当前对象o的值跟新为v+dalta;
} while (!weakCompareAndSetInt(o, offset, v, v + delta));
return v;
}
public final boolean weakCompareAndSetInt(Object o, long offset,
int expected,
int x) {
return compareAndSetInt(o, offset, expected, x);
}
public final native boolean compareAndSetInt(Object o, long offset,
int expected,
int x);

对比观察,其实getAndAddInt就是定义一个变量取到最新的值,然后通过while循环一直更新,其中getIntVolatile和compareAndSetInt都是通过java调用底层c++操作内存。

其中用到了一段标准的锁(自旋锁!):

do {
//v每次都跟新为最新值,所以一直会是期望的值!就执行了++的操作
v = getIntVolatile(o, offset);
//如果当前对象o期望的值等于v,那么将当前对象o的值跟新为v+dalta;
} while (!weakCompareAndSetInt(o, offset, v, v + delta));

缺点

1、循环会耗时

2、一次性只能保证一个共享变量的原子性

3、会存在ABA问题

优点

自带原子性

CAS : ABA问题(狸猫换太子)!

package org.example.cas;
import java.util.concurrent.atomic.AtomicInteger;
public class CASDemo {
public static void main(String[] args) {
AtomicInteger atomicInteger = new AtomicInteger(2020);
//JAVA CAS -> 比较并交换
//期望、更新
//compareAndSet(int expectedValue, int newValue)
//如果我期望的值达到了那么就跟新、否则就不更新; CAS 是CPU的并发原语!
//===============捣乱的线程================
System.out.println(atomicInteger.compareAndSet(2020, 2021));
System.out.println(atomicInteger.compareAndSet(2021, 2020));
//达到期望值更新成功
System.out.println(atomicInteger.get());
//更新后未达到期望值,更新失败
//===============期望的线程================
System.out.println(atomicInteger.compareAndSet(2020, 2021));
System.out.println(atomicInteger.get());
//getAndIncrement number++ 底层如何实现的?
atomicInteger.getAndIncrement();//++方法
}
}
posted @   高同学,你好  阅读(70)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示