当前位置: 首页 > news >正文

CAS 机制


问题分析与思考:

        CAS 是 Java 中 Unsafe 类里面的方法,它的全称是 CompareAndSwap,比较并交换 的意思。

        它的主要功能是能够保证在多线程环境下,对于共享变量的修改的原子性。 举个例子,比如说有这样一个场景(如图),有一个成员变量 state,默认值是 0, 定义了一个方法 doSomething(),这个方法的逻辑是,判断 state 是否为 0 ,如果为 0,就修改成 1。

         这个逻辑看起来没有任何问题,但是在多线程环境下,会存在原子性的问题,因为这里 是一个典型的,Read - Write 的操作。 一般情况下,我们会在 doSomething()这个方法上加同步锁来解决原子性问题。

         但是,加同步锁,会带来性能上的损耗。所以,对于这类场景,我们就可以使用 CAS 机制来进行优化。如下图所示。

        在 doSomething()方法中,我们调用了 unsafe 类中的 compareAndSwapInt()方法来 达到同样的目的,这个方法有四个参数, 分别是:当前对象实例、成员变量 state 在内存地址中的偏移量、预期值 0、期望更改 之后的值 1。

         CAS机制会比较 state 内存地址偏移量对应的值和传入的预期值 0 是否相等,如果相等, 就直接修改内存地址中 state 的值为 1.否则,返回 false,表示修改失败,而这个过程是原子的,不会存在线程安全问题。

 

        CompareAndSwap 是一个 native 方法,实际上它最终还是会面临同样的问题,就是 先从内存地址中读取 state 的值,然后去比较,最后再修改。

        这个过程不管是在什么层面上实现,都会存在原子性问题。 所以呢,CompareAndSwap 的底层实现中,在多核 CPU 环境下,会增加一个 Lock 指令对缓存或者总线加锁,从而保证比较并替换这两个指令的原子性。

结尾:

CAS 主要用在并发场景中,比较典型的使用场景有两个。

        1. 第一个是 JUC 里面 Atomic 的原子实现,比如 AtomicInteger,AtomicLong。

        2. 第二个是实现多线程对共享资源竞争的互斥性质,

            比如在 AQS、 ConcurrentHashMap、ConcurrentLinkedQueue 等都有用到。

http://www.lryc.cn/news/104564.html

相关文章:

  • #P1003. [NOIP2009普及组] 道路游戏
  • python-网络爬虫.regular
  • 手动搭建gateway,项目集成gateway实现Token效果
  • linux下SVN服务器搭建
  • 技术等级 TRL 定义
  • DHorse v1.3.0 发布,基于k8s的发布平台
  • Redis - 缓存的双写一致性
  • opencv03-Mat矩阵API的使用
  • 2023届浙江大学MPA提面A资格经验总结分享
  • BugKu CTF(杂项篇MISC)—想要种子吗
  • 类之间的关系
  • 【蓝图】p40-p43对象引用、变量有效性、实现键盘控制物体自转、简单点名系统
  • vscode设置远程登录和免密登录
  • 今日头条面试真题及答案,软件测试工程师面试秘籍
  • JavaScript Windows 浏览器对象模型
  • 【uniapp 获取缓存及清除缓存】
  • 【vim 学习系列文章 2 - vim 常用插件配置】
  • 【外卖系统】修改菜品
  • 【暑期每日一练】 day11
  • 神经概率语言模型
  • 什么是shadow DOM?
  • 我的 365 天创作纪念日
  • spark-sql : “java.lang.NoSuchFieldError: out“ 异常解决
  • Node.js入门笔记(包含源代码)以及详细解析
  • windows自动化点击大麦app抢购、捡漏,仅支持windows11操作系统
  • vue 拦截 v-html 中 a 标签 href 跳转
  • 分布式id、系统id、业务id以及主键之间的关系
  • 设计模式七:适配器模式(Adapter Pattern)
  • 数据结构---队列
  • chatGPT在软件测试中应用方式有哪些?