CAS是什么?
CAS是CompareAndSwap的缩写,作用是比较与交换。
线程对变量的读取赋值等操作,要先将变量从主内存拷贝自己线程的工作内存空间,在工作内存中进行操作,操作完成后再将变量写回主内存
package com.javaliao.backstage;
import java.util.concurrent.atomic.AtomicInteger;
public class Demo {
//主线程main,程序入口
public static void main(String[] args) {
//原子类整型,在主内存中创建这个对象给初始值为5,默认初始值为0
AtomicInteger atomicInteger = new AtomicInteger(5);
//当线程中的工作内存要写回主内存时,拿第一个参数作为期望值和主内存中的值进行比较,如果期望值和主内存中的值相同都为5,更新值主内存中的值为2019
System.out.println(atomicInteger.compareAndSet(5, 2019)+"\t : "+ atomicInteger.get());
//线程a
new Thread(()->{
//现在主内存中对象的值已经为2019了,期望值为5,和主内存中对象的值不一样,无法将1024写回主内存
System.out.println(atomicInteger.compareAndSet(5, 1024)+"\t : "+ atomicInteger.get());
},"a").start();
}
}
控制台:
这就是为什么我上一章讲的使用AtomicInteger可以解决原子性,因为他在写回主内存时会有一个比较并交互。
AtomicInteger atomicInteger = new AtomicInteger();//默认初始值为0
atomicInteger.getAndIncrement();//加一的操作
调用的getAndIncrement()方法:
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 {
//通过objectFieldOffset方法获取内存地址或者说是内存偏移量
valueOffset = unsafe.objectFieldOffset
(AtomicInteger.class.getDeclaredField("value"));
} catch (Exception ex) { throw new Error(ex); }
}
private volatile int value;
public final int getAndIncrement() {
//this是当前对象,valueOffset是内存地址,1是写死的value值
return unsafe.getAndAddInt(this, valueOffset, 1);
}
可以看到方法体内又通过调用Unsafe类中的getAndAddInt()方法
源码分析:
//获取当前对象的地址值,var1是这个对象,var2的内存地址,相当于当前线程先从主内存中拷贝变量的值到自己的工作内存中var5就是工作内存中的变量值
var5 = this.getIntVolatile(var1, var2)
//调用CAS方法类型是Int类型的,当前对象(var1)的地址的值(var2的值)和期望值(var5)相同,就将更新值(var5+var4)写回主内存
this.compareAndSwapInt(var1, var2, var5, var5 + var4)
//只有比较成功才可以写回
还想了解compareAndSwapInt方法的可以看下图:
而Unsafe类是jdk中rt.jar包下的
小总结:
CAS有什么缺点?
第一个缺点:
第二个缺点:
第三个缺点:
引出来的ABA问题:只管结果,不管过程
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?