CAS核心思想、底层实现
★ 1、CAS 是什么
CAS 是比较并交换,是实现并发算法时常用到的一种技术。 当内存的值和期望的值相等时,进行更新 ,否则 什么都不做 或 重来 。
CAS 的底层实现:是靠硬件实现的,靠硬件的原子性实现, CAS是一条CPU的原子指令 ( cmpxchg指令 ), 不会造成所谓的数据不一致问题 。
重来==> 自旋
CAS 类似乐观锁,乐观的认为别人没有修改,当值还是预期值,就进行修改,否则可能什么都不做,或者重来。
★ 2、CAS 应用举例
- 原子操作类,比如整型的原子操作类的compareAndSet方法
- 我的博客项目中,在更新文章浏览次数时,当前 内存的文章浏览次数 和 期望中的 数据库的文章浏览次数 进行比较,如果是相同的,则加1,否则 什么都不做
3、原子类
■ 原子类==> 底层思想/工作原理 CAS ==> Unsafe 类的CPU 原语级别的汇编操作
-
CAS 是靠硬件实现的,靠硬件的原子性实现 , CAS是一条CPU的原子指令 ( cmpxchg指令 ), 不会造成所谓的数据不一致问题 ,
Unsafe提供的CAS方法(如compareAndSwapXXX)底层实现即为CPU指令cmpxchg。
■ AtomicInteger 类主要利用 CAS + volatile 和 native 方法来 保证原子操作,从而避免 synchronized 的高开销 ,执行效率大为提升。
new AtomicInteger().compareAndSet(0, 1); // 底层实现 public final int getAndAdd(int delta) { return unsafe.getAndAddInt(this, valueOffset, delta); } public final boolean compareAndSet(int expect, int update) { return unsafe.compareAndSwapInt(this, valueOffset, expect, update); } new AtomicInteger().getAndAdd(1);//获取到当前值并加1 // 底层实现 public final int getAndAdd(int delta) { return unsafe.getAndAddInt(this, valueOffset, delta); } 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; }
■ 工作中,不建议使用Unsafe 类,类名就提示你了"不安全"!
4、Unsafe 类
-
是CAS的核心类
-
可以
像C的指针一样直接操作内存
-
Unsafe类中的所有方法都是native修饰的
,Unsafe类中的方法都可以直接调用操作系统底层资源去执行相应任务
//原子类 public final int getAndIncrement() { return unsafe.getAndAddInt(this, valueOffset, 1); } private volatile int value;
变量 valueOffset ,表示该变量值在内存中的 偏移地址 ,因为 Unsafe就是根据内存偏移地址获取数据 的。
变量value用volatile修饰,保证了多线程之间的内存可见性。每次获取的值都是最新的。
5、CAS 带来的问题
- 循环时间长,可能死循环,开销很大
-
ABA 问题
- 解决ABA 问题: 带版本号的原子引用 AtomicStampedReference
如果本文对你有帮助的话记得给一乐点个赞哦,感谢!
「其他文章」
- 线程池底层原理详解与源码分析
- 30分钟掌握 Webpack
- 线性回归大结局(岭(Ridge)、 Lasso回归原理、公式推导),你想要的这里都有
- 【前端必会】webpack loader 到底是什么
- 中心化决议管理——云端分析
- HashMap底层原理及jdk1.8源码解读
- 详解JS中 call 方法的实现
- 打印 Logger 日志时,需不需要再封装一下工具类?
- 初识设计模式 - 代理模式
- 密码学奇妙之旅、01 CFB密文反馈模式、AES标准、Golang代码
- Springboot之 Mybatis 多数据源实现
- CAS核心思想、底层实现
- 面试突击86:SpringBoot 事务不回滚?怎么解决?
- 基于electron vue element构建项目模板之【打包篇】
- MiniWord .NET Word模板引擎,藉由Word模板和数据简单、快速生成文件。
- 认识线程,初始并发
- 1-VSCode搭建GD32开发环境
- 初识设计模式 - 原型模式
- 线程安全问题的产生条件、解决方式
- 2>&1到底是什么意思?