CAS(Compare And Swap) 详解
CAS实例
class AccountSafe implements Account {private AtomicInteger balance;public AccountSafe(Integer balance) {this.balance = new AtomicInteger(balance);}public Integer getBalance() {return balance.get();}public void withdraw(Integer amount) {// 需要不断尝试,直到成功为止while (true) {// 比如拿到了旧值 1000int prev = balance.get();// 在这个基础上 1000-10 = 990int next = prev - amount;/*compareAndSet 正是做这个检查,在 set 前,先比较 prev 与当前值- 不一致了,next 作废,返回 false 表示失败比如,别的线程已经做了减法,当前值已经被减成了 990那么本线程的这次 990 就作废了,进入 while 下次循环重试- 一致,以 next 设置为新值,返回 true 表示成功*/if (balance.compareAndSet(prev, next)) {break;}}// 可以简化为下面的方法// balance.addAndGet(-1 * amount);}}
过程分析
CAS和volatile的关系
在java层面是原子类,原子类的底层原来是通过CAS实现的。。查看AtomicInteger的源码,因为要使每个线程get()的都是最新的值(即主内存的值),所以需要对该字段使用volatile关键字修饰。
private volatile int value;/*** Gets the current value.** @return the current value*/public final int get() {return value;}
CAS的底层原理
其实 CAS 的底层是 lock cmpxchg 指令(X86 架构),在单核 CPU 和多核 CPU 下都能够保证【比较-交换】的原子性。
为什么无锁效率高
- 无锁情况下,即使重试失败,线程始终在高速运行,没有停歇,而 synchronized 会让线程在没有获得锁的时候,发生上下文切换,进入阻塞。打个比喻
- 线程就好像高速跑道上的赛车,高速运行时,速度超快,一旦发生上下文切换,就好比赛车要减速、熄火,等被唤醒又得重新打火、启动、加速… 恢复到高速运行,代价比较大
- 但无锁情况下,因为线程要保持运行,需要额外 CPU 的支持,CPU 在这里就好比高速跑道,没有额外的跑道,线程想高速运行也无从谈起,虽然不会进入阻塞,但由于没有分到时间片,仍然会进入可运行状态,还是会导致上下文切换。
- 总结: 使用多核cpu的支持
CAS 的特点
结合 CAS 和 volatile 可以实现无锁并发,适用于线程数少、多核 CPU 的场景下。
- CAS 是基于乐观锁的思想:最乐观的估计,不怕别的线程来修改共享变量,就算改了也没关系,我吃亏点再重试呗。
- synchronized 是基于悲观锁的思想:最悲观的估计,得防着其它线程来修改共享变量,我上了锁你们都别想改,我改完了解开锁,你们才有机会。
- CAS 体现的是无锁并发、无阻塞并发,请仔细体会这两句话的意思
- 因为没有使用 synchronized,所以线程不会陷入阻塞,这是效率提升的因素之一
- 但如果竞争激烈,可以想到重试必然频繁发生,反而效率会受影响
CAS(Compare And Swap) 详解相关推荐
- 猫头鹰的深夜翻译:Java中的CAS(Compare And Swap)
题目要求 在我们深入了解CAS(Compare And Swap)策略以及它是如何在AtomicInteger这样的原子构造器中使用的,首先来看一下这段代码: public class MyApp { ...
- 非阻塞同步算法与CAS(Compare and Swap)无锁算法
锁(lock)的代价 锁是用来做并发最简单的方式,当然其代价也是最高的.内核态的锁的时候需要操作系统进行一次上下文切换,加锁.释放锁会导致比较多的上下文切换和调度延时,等待锁的线程会被挂起直至锁释放. ...
- CAS(Compare and swap)比较并交换算法解析
CAS说明 CAS全称是Compare and swap.字面翻译的意思就是比较并交换. CAS可以用来实现乐观锁,CAS中没有线程的上下文切换,减少了不必要的开销 说明:本文解析的JDK源码为ope ...
- CAS 单点登录使用详解
============================================================================== 开发环境 :MyEclipse6.5+to ...
- Java中的CAS(compare and swap)
定义: 拿着寄存器/某个内存 中的值和另外一个内存的值进行比较,如果值相同了,就把两者交换 boolean CAS(address, expectValue, swapValue){if(&a ...
- Beyond Compare软件使用详解
方法/步骤 步骤一 下载Beyond Compare软件,我们可以到Beyond Compare中文官网进行下载,下载地址:Beyond Compare 4中文版免费下载-Beyond Compare ...
- Compare to 方法详解
compareTo() 方法用于将 Number 对象与方法的参数进行比较.可用于比较 Byte, Long, Integer等.该方法用于两个相同数据类型的比较,两个不同类型的数据不能用此方法来比较 ...
- Java中CAS详解
转载自 Java中CAS详解 在JDK 5之前Java语言是靠synchronized关键字保证同步的,这会导致有锁 锁机制存在以下问题: (1)在多线程竞争下,加锁.释放锁会导致比较多的上下文切换 ...
- java unsafe 详解_Java CAS操作与Unsafe类详解
一.复习 计算机内存模型,synchronized和volatile关键字简介 二.两者对比 sychronized和volatile都解决了内存可见性问题 不同点: (1)前者是独占锁,并且存在者上 ...
- 详解各种锁:CAS、共享锁、排它锁、互斥锁、悲观锁、乐观锁、行级锁、表级锁、页级锁、死锁、JAVA对CAS的支持、ABA问题、AQS原理
共享锁(S锁) 又称为读锁,可以查看但无法修改和删除的一种数据锁.如果事务T对数据A加上共享锁后,则其他事务只能对A再加共享锁,不能加排它锁.获准共享锁的事务只能读数据,不能修改数据. 共享锁下其它用 ...
最新文章
- mybatis-mapper
- pgsql数据库默认配置事务类型_PostgreSQL基础教程之:初始化配置
- UNIX再学习 -- 文件描述符
- Java黑皮书课后题第4章:*4.7(顶点坐标)假设一个正五边形的中心位于(0,0),其中一个点位于0点位置。编写程序,提示用户输入正五边形外接圆的半径,显示p1到p5的5个坐标,保留两位小数
- ansible 判断和循环
- 【最短路径Floyd算法详解推导过程】看完这篇,你还能不懂Floyd算法?还不会?...
- 发电厂电气部分第三版pdf_火力发电厂电气主接线的特点
- vscode代码库登录配置_VSCode 配置 Sonar Lint支持代码检查提效
- 使用navigator对象,输出当前浏览器的信息
- 图片像QQ有消息闪动的代码:
- 150家通用经销商决定退出凯迪拉克品牌 因不愿投资于销售电动车
- 实现(手撕)遗传算法与集成学习-人工智能大作业(特征选择其实是乱选的,抄的别人的,,,)
- 【渝粤教育】电大中专学前儿童社会教育 (2)作业 题库
- CAS简介和无锁队列的实现
- 企业微信应用权限签名api记录
- Linux下网络抓包工具(ngrep)
- pc网页唤起QQ、企业微信、skype、whatsApp等
- c++ double 截取_C/C++ double取余函数
- 宝莱坞机器人 西瓜_《宝莱坞机器人之恋》电影完整版免费在线观看_2010西瓜影音 - 辛集电影院...
- Request failed with status code 504怎么解决
热门文章
- 易筋SpringBoot 2.2 | 第三十二篇:Redis Docker入门
- android.mk 依赖关系,Android NDK学习(二):编译脚本语法Android.mk和Application.mk
- 微型计算机主机作用,微型计算机的主机包括()。
- java代码输出我喜欢你_程序员七夕如何表白:朕只爱一个皇后!(单例模式)...
- C++例4.11 求两个或三个正整数中的最大数,用带有默认参数的函数实现。
- 146.LRU缓存机制
- 特征的标准化和归一化
- TypeError: 'list' object is not callable
- 计算机插本2a院校,广东省专插本2A院校有哪些
- C语言的结构变量定义规则,嵌入式学习笔记:c语言结构体的定义和使用