CAS 与 volatile

news2024/10/6 20:39:06

 

目录

 

CAS

volatile

为什么无锁效率高

CAS 的特点


CAS

        AtomicInteger 内部并没有用锁来保护共享变量的线程安全。那么它是如何实现的呢?
public void withdraw(Integer amount) {
         while(true) {
         // 需要不断尝试,直到成功为止
             while (true) {
                 // 比如拿到了旧值 1000
                 int prev = balance.get();
                 // 在这个基础上 1000-10 = 990
                 int next = prev - amount;
                 /*
                     compareAndSet 正是做这个检查,在 set 前,先比较 prev 与当前值
                     - 不一致了,next 作废,返回 false 表示失败
                     比如,别的线程已经做了减法,当前值已经被减成了 990
                     那么本线程的这次 990 就作废了,进入 while 下次循环重试
                     - 一致,以 next 设置为新值,返回 true 表示成功
                 */
                 if (balance.compareAndSet(prep, next)) {
                     break;
                 }
         }
     }
}
        其中的关键是 compareAndSet ,它的简称就是 CAS (也有 Compare And Swap 的说法),它必须是原子操作。

        注意
                其实 CAS 的底层是 lock cmpxchg 指令( X86 架构),在单核 CPU 和多核 CPU 下都能够保证【比较 - 交 换】的原子性。
                在多核状态下,某个核执行到带 lock 的指令时, CPU 会让总线锁住,当这个核把此指令执行完毕,再开启总线。这个过程中不会被线程的调度机制所打断,保证了多个线程对内存操作的准确性,是原子的。

volatile

        获取共享变量时,为了保证该变量的可见性,需要使用 volatile 修饰。
        它可以用来修饰成员变量和静态成员变量,他可以避免线程从自己的工作缓存中查找变量的值,必须到主存中获取 它的值,线程操作 volatile 变量都是直接操作主存。即一个线程对 volatile 变量的修改,对另一个线程可见。
        注意
        volatile 仅仅保证了共享变量的可见性,让其它线程能够看到最新值,但不能解决指令交错问题(不能保证原子性)
        CAS 必须借助 volatile 才能读取到共享变量的最新值来实现【比较并交换】的效果

为什么无锁效率高

        无锁情况下,即使重试失败,线程始终在高速运行,没有停歇,而 synchronized 会让线程在没有获得锁的时 候,发生上下文切换,进入阻塞。打个比喻, 线程就好像高速跑道上的赛车,高速运行时,速度超快,一旦发生上下文切换,就好比赛车要减速、熄火, 等被唤醒又得重新打火、启动、加速... 恢复到高速运行,代价比较大
        但无锁情况下,因为线程要保持运行,需要额外 CPU 的支持, CPU 在这里就好比高速跑道,没有额外的跑 道,线程想高速运行也无从谈起,虽然不会进入阻塞,但由于没有分到时间片,仍然会进入可运行状态,还 是会导致上下文切换。

CAS 的特点

        结合 CAS volatile 可以实现无锁并发,适用于线程数少、多核 CPU 的场景下。
                CAS 是基于乐观锁的思想:最乐观的估计,不怕别的线程来修改共享变量,就算改了也没关系,我吃亏点再 重试呗。
                synchronized 是基于悲观锁的思想:最悲观的估计,得防着其它线程来修改共享变量,我上了锁你们都别想 改,我改完了解开锁,你们才有机会。
                CAS 体现的是无锁并发、无阻塞并发,请仔细体会这两句话的意思
                        因为没有使用 synchronized,所以线程不会陷入阻塞,这是效率提升的因素之一
                        但如果竞争激烈,可以想到重试必然频繁发生,反而效率会受影响

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1638492.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C#知识|泛型集合List相关方法

哈喽,你好,我是雷工! 以下为泛型集合List相关方法的学习笔记。 01 集合定义 集合定义的时候,无需规定元素的个数。 02 泛型说明 泛型表示一种程序特性,也就是在定义的时候,无需指定特定的类型&#xff…

STM32 看门狗WDG

一、看门狗(Watchdog) 看门狗可以监控程序的运行状态,当程序因为设计漏洞、硬件故障、电磁干扰等原因,出现卡死或跑飞现象时,看门狗能及时复位程序,避免程序陷入长时间的罢工状态,保证系统的可靠…

2024五一数学建模A题思路代码与论文分析

2024五一数学建模A题完整代码和成品论文获取↓↓↓↓↓ https://www.yuque.com/u42168770/qv6z0d/gyoz9ou5upvkv6nx?singleDoc# 2024五一数学建模A题钢板最优切割路径问题需要建立的模型和算法: 图论 最短路径算法(Dijkstra算法、Floyd算法等) 动态规划 网格化离散建模 …

Go语言在Web开发中有哪些常用框架?

文章目录 1. Gin原因和解决方案示例代码 2. Echo原因和解决方案示例代码 3. Revel原因和解决方案示例代码 4. Buffalo原因和解决方案示例代码 总结 Go语言在Web开发中拥有许多优秀的框架,这些框架帮助开发者快速构建稳定且高效的Web应用。下面是一些常用的Go语言Web…

# 从浅入深 学习 SpringCloud 微服务架构(七)Hystrix(4)

从浅入深 学习 SpringCloud 微服务架构(七)Hystrix(4) 一、hystrix:使用 turbine 聚合所有的 hytrix 的监控数据测试。创建父工程 spring_cloud_hystrix_demo,导入相关依赖坐标。并在父工程 spring_cloud_…

uniapp 桌面应用插件 Ba-Launcher

简介(下载地址) Ba-Launcher 可以让你的应用成为简单的桌面应用,如需扩展功能,请联系我。 截图展示 可关注博客,实时更新最新插件: uniapp 常用原生插件大全 使用方法 使用方法也很简单,在插…

python中的进程线程和协程

目录 进程(Process)多进程代码实例 线程(Thread)多线程存在原因及其缺点多线程代码实例 协程(Coroutine)协程的优点协程代码实例 进程、线程和协程适合的任务性质和环境多进程更适合的场景多线程更适合的场…

定了!嫦娥六号任务计划5月3日发射 | 最新快讯

来源:央视新闻客户端 今天(5 月 1 日),国家航天局发布最新消息,经工程任务指挥部综合研判决策,探月工程四期嫦娥六号任务计划 5 月 3 日实施发射。 发射窗口是指适合火箭发射的时间范围。此次任务在综合考虑…

Devops部署maven项目

这里讲下应用k8s集群devops持续集成部署maven项目的流程。 failed to verify certificate: x509: certificate signed by unknown authority 今天在执行kubectl get nodes的时候报的证书验证问题,看了一圈首次搭建k8s的都是高频出现的问题。 couldn’t get curren…

Unity LensFlare 入门

概述 在项目的制作过程中,太阳光的使用一定是不可缺少的部分,但是如果想实现真实太阳光眼睛看到的镜头炫光效果,那这部分的内容一定不要错过喔,接下来让我们来学习这部分的内容吧! Hale(光环效果) Color:…

JavaEE_操作系统之进程(计算机体系,,指令,进程的概念、组成、特性、PCB)

一、冯诺依曼体系(Von Neumann Architecture) 现代的计算机, 大多遵守冯诺依曼体系结构 CPU 中央处理器: 进行算术运算和逻辑判断.存储器: 分为外存和内存, 用于存储数据(使用二进制方式存储)输入设备: 用户给计算机发号施令的设备.输出设备: 计算机个…

黑马头条Day02_app端文章查看,静态化freemarker,分布式文件系统minIO

文章目录 app端文章查看,静态化freemarker,分布式文件系统minIO1)文章列表加载1.1)需求分析1.2)表结构分析1.3)导入文章数据库1.3.1)导入数据库1.3.2)导入对应的实体类 1.4)实现思路1.5)接口定义1.6)功能实现1.6.1):导入heima-leadnews-article微服务&am…

Springboot+Vue项目-基于Java+MySQL的智慧校园管理系统(附源码+演示视频+LW)

大家好!我是程序猿老A,感谢您阅读本文,欢迎一键三连哦。 💞当前专栏:Java毕业设计 精彩专栏推荐👇🏻👇🏻👇🏻 🎀 Python毕业设计 &…

1700java进销存管理系统Myeclipse开发sqlserver数据库web结构java编程计算机网页项目

一、源码特点 java web进销存管理系统是一套完善的java web信息管理系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发,数据库为sqlser…

6.k8s中的secrets资源

一、Secret secrets资源,类似于configmap资源,只是secrets资源是用来传递重要的信息的; secret资源就是将value的值使用base64编译后传输,当pod引用secret后,k8s会自动将其base64的编码,反编译回正常的字符…

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-6.5--I.MX6U启动方式

前言: 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM(MX6U)裸机篇”视频的学习笔记,在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…

LeetCode 69—— x 的平方根

阅读目录 1. 题目2. 解题思路一3. 代码实现一4. 解题思路二5. 代码实现二 1. 题目 2. 解题思路一 二分查找法,对于整数 i ∈ [ 0 , x ] i \in [0,x] i∈[0,x],我们判断 i 2 i^2 i2 和 x x x 的关系,然后找到最后一个平方小于等于 x x x …

DRF权限组件源码分析

DRF权限组件源码分析 权限组件相关配置同认证组件 0 认证组件的两种返回值 有权限,返回True,程序正常进行无权限,返回False,程序抛出异常 1 单视图应用 2 多视图应用 3 单视图多视图结合 在drf中,默认优先去全局中…

java大学生兼职就业求职招聘管理系统hg241-vue+Springboot

大学生兼职中心系统是一个帮助学生正确安排课余时间的系统,同学们可以根据课程的多少来选择不同的兼职工作,而商家也可以从不同的学生中挑选适合的人选。既然是兼职,那么这些工作基本都是按照小时来计算工资的,也许不会很高&#…

【Linux】项目自动化构建工具make/makefile的简单使用

使用步骤 1) 编写 创建 makefile 文件 vim makefile用 vim 打开名为 makefile 的文件,存在该文件则打开编辑,不存在则创建并打开.在 makefile 文件中编写需要编译的文件 test:test.cppg -o test test.cpp第一行: 冒号左侧为编译后的可执行文件名,可以随便取. 冒号右侧为依赖…