目录

  • 一、CAS的基本概念
  • 二、CAS算法理解
  • 三、CAS开销
  • 四、CAS算法在JDK中的应用

一、CAS的基本概念

CAS:Compare and Swap,即比较再交换,是一种硬件对并发的支持,针对多处理器操作而设计的处理器中的一种特殊指令,用于管理对共享数据的并发访问

jdk5增加了并发包java.util.concurrent.*,其下面的类使用CAS算法实现了区别于synchronouse同步锁的一种乐观锁。JDK 5之前Java语言是靠synchronized关键字保证同步的,这是一种独占锁,也是是悲观锁

二、CAS算法理解

对CAS的理解,CAS是一种无锁算法

CAS有3个操作数:

需要读写的内存值 V
进行比较的值 A
拟写入的新值 B

当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做

CAS比较与交换的伪代码可以表示为:

do{备份旧数据;基于旧数据构造新数据;
}while(!CAS( 内存地址,备份的旧数据,新数据 ))

注:t1,t2线程是同时更新同一变量56的值

因为t1和t2线程都同时去访问同一变量56,所以他们会把主内存的值完全拷贝一份到自己的工作内存空间,所以t1和t2线程的预期值都为56。

假设t1在与t2线程竞争中线程t1能去更新变量的值,而其他线程都失败。(失败的线程并不会被挂起,而是被告知这次竞争中失败,并可以再次发起尝试)。t1线程去更新变量值改为57,然后写到内存中。此时对于t2来说,内存值变为了57,与预期值56不一致,就操作失败了(想改的值不再是原来的值)。

(上图通俗的解释是:CPU去更新一个值,但如果想改的值不再是原来的值,操作就失败,因为很明显,有其它操作先改变了这个值。

就是指当两者进行比较时,如果相等,则证明共享数据没有被修改,替换成新值,然后继续往下运行;如果不相等,说明共享数据已经被修改,放弃已经所做的操作,然后重新执行刚才的操作。容易看出 CAS 操作是基于共享数据不会被修改的假设,采用了类似于数据库的commit-retry 的模式。当同步冲突出现的机会很少时,这种假设能带来较大的性能提升。

三、CAS开销

前面说过了,CAS(比较并交换)是CPU指令级的操作,只有一步原子操作,所以非常快。而且CAS避免了请求操作系统来裁定锁的问题,不用麻烦操作系统,直接在CPU内部就搞定了。但CAS就没有开销了吗?不!有cache miss的情况。这个问题比较复杂,首先需要了解CPU的硬件体系结构:

上图可以看到一个8核CPU计算机系统,每个CPU有cache(CPU内部的高速缓存,寄存器),管芯内还带有一个互联模块,使管芯内的两个核可以互相通信。在图中央的系统互联模块可以让四个管芯相互通信,并且将管芯与主存连接起来。数据以“缓存线”为单位在系统中传输,“缓存线”对应于内存中一个 2 的幂大小的字节块,大小通常为 32 到 256 字节之间。当 CPU 从内存中读取一个变量到它的寄存器中时,必须首先将包含了该变量的缓存线读取到 CPU 高速缓存。同样地,CPU 将寄存器中的一个值存储到内存时,不仅必须将包含了该值的缓存线读到 CPU 高速缓存,还必须确保没有其他 CPU 拥有该缓存线的拷贝。

比如,如果 CPU0 在对一个变量执行“比较并交换”(CAS)操作,而该变量所在的缓存线在 CPU7 的高速缓存中,就会发生以下经过简化的事件序列:

(1)CPU0 检查本地高速缓存,没有找到缓存线。
(2)请求被转发到 CPU0 和 CPU1 的互联模块,检查 CPU1的本地高速缓存,没有找到缓存线。
(3)请求被转发到系统互联模块,检查其他三个管芯,得知缓存线被 CPU6和 CPU7 所在的管芯持有。
(4)请求被转发到 CPU6 和 CPU7 的互联模块,检查这两个 CPU 的高速缓存,在 CPU7 的高速缓存中找到缓存线。
(5)CPU7 将缓存线发送给所属的互联模块,并且刷新自己高速缓存中的缓存线。
(6)CPU6 和 CPU7的互联模块将缓存线发送给系统互联模块。
(7)系统互联模块将缓存线发送给 CPU0 和 CPU1 的互联模块。
(8)CPU0 和 CPU1的互联模块将缓存线发送给 CPU0 的高速缓存。
(9)CPU0 现在可以对高速缓存中的变量执行 CAS 操作了

以上是刷新不同CPU缓存的开销。最好情况下的 CAS 操作消耗大概 40 纳秒,超过 60 个时钟周期。这里的“最好情况”是指对某一个变量执行 CAS 操作的 CPU 正好是最后一个操作该变量的CPU,所以对应的缓存线已经在 CPU 的高速缓存中了,类似地,最好情况下的锁操作(一个“round trip 对”包括获取锁和随后的释放锁)消耗超过 60 纳秒,超过 100 个时钟周期。这里的“最好情况”意味着用于表示锁的数据结构已经在获取和释放锁的 CPU 所属的高速缓存中了。锁操作比 CAS 操作更加耗时,是因深入理解并行编程为锁操作的数据结构中需要两个原子操作。缓存未命中消耗大概 140 纳秒,超过 200 个时钟周期。需要在存储新值时查询变量的旧值的 CAS 操作,消耗大概 300 纳秒,超过 500 个时钟周期。想想这个,在执行一次 CAS 操作的时间里,CPU 可以执行 500 条普通指令。这表明了细粒度锁的局限性。

以下是cache miss cas 和lock的性能对比:

四、CAS算法在JDK中的应用

在原子类变量中,如java.util.concurrent.atomic中的AtomicXXX,都使用了这些底层的JVM支持为数字类型的引用类型提供一种高效的CAS操作,而在java.util.concurrent中的大多数类在实现时都直接或间接的使用了这些原子变量类。

Java 1.7中AtomicInteger.incrementAndGet()的实现源码为:

public final int incrementAndGet(){for(;;){int current = get();int next = current + 1;if(compareAndSet(current,next))return next;}
}public final boolean compareAndSet(int expect,int update){return unsafe.compareAndSwapInt(this,valueOffset,expect,update);
}

由此可见,AtomicInteger.incrementAndGet的实现用了乐观锁技术,调用了类sun.misc.Unsafe库里面的 CAS算法,用CPU指令来实现无锁自增。所以,AtomicInteger.incrementAndGet的自增比用synchronized的锁效率倍增

深入解析CAS算法原理相关推荐

  1. 深入理解CAS算法原理

    转载自 深入理解CAS算法原理 1.什么是CAS? CAS:Compare and Swap,即比较再交换. jdk5增加了并发包java.util.concurrent.*,其下面的类使用CAS算法 ...

  2. 面试:CAS算法原理

    1.什么是CAS? CAS:Compare and Swap,即比较再交换. jdk5增加了并发包java.util.concurrent.*,其下面的类使用CAS算法实现了区别于synchronou ...

  3. ARCore Depth API 深度解析:算法原理及开发细节

    Google ARCore 1.18 近期发布重大更新,通过 Depth API(深度 API)解决了一直横亘在开发者面前的深度理解和遮挡难题.文末更有 7/18 技术直播分享活动,不要错过! Dep ...

  4. java cas原理_Java并发之原子变量及CAS算法-上篇

    Java并发之原子变量及CAS算法-上篇 编辑 ​ 概述 本文主要讲在Java并发编程的时候,如果保证变量的原子性,在JDK提供的类中是怎么保证变量原子性的呢?.对应Java中的包是:java.uti ...

  5. 索引算法原理解析(B-tree以及磁盘存储原理)

    刚开始学习的时候,百度去查,但发现好多说得太复杂不好理解,结合各个文章总结一下(建议大概看文字,不理解不要紧,然后再看图的执行步骤然后在结合文字,这样一切就清晰好多) B-tree,B是balance ...

  6. CAS算法-实现原理

    目录 CAS是什么? CAS解决了什么问题? CAS存在什么问题? CAS有哪些应用场景? cas的实现 最后 CAS是什么? CAS的全称为Compare and swap 比较并交换.CAS又经常 ...

  7. python文件去重算法_使用Python检测文章抄袭及去重算法原理解析

    在互联网出现之前,"抄"很不方便,一是"源"少,而是发布渠道少:而在互联网出现之后,"抄"变得很简单,铺天盖地的"源"源 ...

  8. python去重算法_使用Python检测文章抄袭及去重算法原理解析

    在互联网出现之前,"抄"很不方便,一是"源"少,而是发布渠道少:而在互联网出现之后,"抄"变得很简单,铺天盖地的"源"源 ...

  9. p.563算法原理解析

    p.563算法原理解析 1.概览 ​ 下图展示了,人工主观语音评估mos-lqs,双端和单端客观语音评估mos-lqo这三种方法的差异. ​ p563算法可以被想象成一个专家使用测试设备如传统的听筒侦 ...

  10. SEO技术深度解析(TF-IDF算法原理及公式)

    做为SEO行业老鸟应该听说过TF-IDF算法,TF-IDF算法属于搜索引擎中的核心部分.TF-IDF算法是增加相关词的覆盖率,以及高优布局关键词密度,从而在百度谷歌等搜索引擎内容质量这一项上的排名加分 ...

最新文章

  1. rpcgen的简单讲解及例子程序
  2. 有计算机二级证书当兵有好处吗,大学生拿到这个证书可享受的福利,当兵有什么不一样?...
  3. 【Linux】【服务器】 CentOS7下卸载MySQL详细过程步骤
  4. 首页优化加载(聊聊百度移动端首页前端优化)
  5. 1059 Prime Factors
  6. java 容器_JAVA的容器
  7. 读:[你必须知道的.NET] 第五回:深入浅出关键字---把new说透
  8. contenttype添加field
  9. 乐观锁 与 悲观锁 总结
  10. ES11新特性_可选链操作符---JavaScript_ECMAScript_ES6-ES11新特性工作笔记064
  11. 二叉树进阶之寻找一棵二叉树中的最大二叉搜索子树
  12. CF120F Spiders 题解
  13. 三安集成长沙碳化硅制造基地下半年启动投产;龙芯中科正式发布完全自主指令集架构 | 美通企业日报...
  14. 职场最高级的聪明是靠谱,到底一个人怎样才算真正靠谱?
  15. 《机器学习实战》——第3章 决策树
  16. 理解vuex实现的原理
  17. 常用的连续概率分布汇总
  18. Ruby on Rails社区网站开发
  19. 一个大学教授的精彩演讲~~
  20. 花了一个月时间折腾Hackintosh的历程

热门文章

  1. Javaweb安全——Java类加载机制
  2. 阿里云上线视频云剪辑 快速产出PGC短视频不再是问题!
  3. linux ubuntu extmail,ubuntu下extmail安装参考地址
  4. mysql导入access2016_将 Access 2.0 和 Access 95 数据库导入到当前版本
  5. 前端框架MVVM是什么(整理)
  6. java动态生成HTML文件
  7. 阿铭Linux_网站维护学习笔记20190410
  8. cmd命令查询电脑序列号_WINDOWS 用命令行 找到PC序列号以及计算机名称
  9. Java实现MD5加密工具类
  10. 安全基础-防火墙四种登录方式 SSH Telnet SSH