前言:在对AQS框架进行分析的过程中发现了很多CAS操作,因此有必要对CAS进行一个梳理,也便更清楚的了解其原理。

1.CAS是什么

CAS,是compare and swap的缩写,中文含义:比较交换。

CAS操作包含三个操作数——需要读写的内存值(V)、预期原值[进行比较的值](A)和新值(B)。如果V的值与A值匹配时,那么就将该内存位置的值更新为新值,否则不做任何操作。

CAS用于同步的方式是从地址V处读取值A,在执行一些列计算后获得新值B,如果此时内存V处的值和预期值A相等,则将V处值更新为B,此时CAS操作成功。

2.CAS原理

在intel的CPU中,Java CAS操作通过cmpxchg指令来完成原子操作,通过JNI来完成非阻塞算法,J.U.C包都建立在CAS上,对比synchronized阻塞算法,通过CAS在性能上有了很大的提升。

CAS的操作都集中在Unsafe类中,这里看compareAndSwapInt的源码:

通过源码可以看出该方法为native的,它会去调底层的C++代码。对应intel x86处理器源代码片段:

os::is_MP()命令会根据当前处理器类型来决定是否为cmpxchg指令添加lock前缀。如果是多处理器,就会在cmpxchg指令前加上lock前缀,否则单处理器按书序一致性执行,不需要内存屏障的效果。

3.CAS的缺点

CAS虽然可以很高效的解决原子操作问题,但它仍然存在三大问题。

#1.ABA问题

ABA问题产生的原因:CAS操作的时候需要检查值有没有发生变化,如果没有发生变化则进行更新,但如果一个值原来是A,接着变成B,后来又变成A,在CAS操作的时候会发现它的值没有发生变化,但实际上值发生了变化。因此这种操作是有问题的。

解决思路:使用版本号。在变量前面追加上版本号,每次变量更新的时候把版本号自增,那么A-B-A 就会变成1A-2B-3A。从Java1.5开始JDK的atomic包里提供了一个类AtomicStampedReference来解决ABA问题。这个类的compareAndSet方法作用是首先检查当前引用是否等于预期引用,并且当前标志是否等于预期标志,如果全部相等,则以原子方式将该引用和该标志的值设置为给定的更新值。

#2.循环时间开销大

自旋CAS如果长时间不成功,会给CPU带来非常大的执行开销。

#3.只能保证一个共享变量的原子操作

因为Java中的CAS操作只是对CPU的cmpxchg指令的一层封装,它的功能就是一次只能原子的修改一个变量,可以加锁来解决这个问题。或者利用AtomicReference把多个变量放入一个对象中进行CAS操作。

总结

对于CAS记住比较交换,相同则更新,以及CAS的在AQS的重要地位。

参考:

https://blog.52itstyle.com/archives/948/


by Shawn Chen, 2019.1.30日,下午。

Java中的CAS原理的更多相关文章

  1. Java中的CAS实现原理

    一.什么是CAS? 在计算机科学中,比较和交换(Conmpare And Swap)是用于实现多线程同步的原子指令. 它将内存位置的内容与给定值进行比较,只有在相同的情况下,将该内存位置的内容修改为新 ...

  2. Java并发--Java中的CAS操作和实现原理

    版权声明:本文为博主原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/CringKong/article/deta ...

  3. 沉淀再出发:java中的CAS和ABA问题整理

    沉淀再出发:java中的CAS和ABA问题整理 一.前言 在多并发程序设计之中,我们不得不面对并发.互斥.竞争.死锁.资源抢占等等问题,归根到底就是读写的问题,有了读写才有了增删改查,才有了所有的一切 ...

  4. java高并发系列 - 第21天:java中的CAS操作,java并发的基石

    这是java高并发系列第21篇文章. 本文主要内容 从网站计数器实现中一步步引出CAS操作 介绍java中的CAS及CAS可能存在的问题 悲观锁和乐观锁的一些介绍及数据库乐观锁的一个常见示例 使用ja ...

  5. 深入介绍Java中的锁[原理、锁优化、CAS、AQS]

    1.为什么要用锁? 锁-是为了解决并发操作引起的脏读.数据不一致的问题. 2.锁实现的基本原理 2.1.volatile Java编程语言允许线程访问共享变量, 为了确保共享变量能被准确和一致地更新, ...

  6. Java中的锁[原理、锁优化、CAS、AQS]

    1.为什么要用锁? 锁-是为了解决并发操作引起的脏读.数据不一致的问题. 2.锁实现的基本原理 2.1.volatile Java编程语言允许线程访问共享变量, 为了确保共享变量能被准确和一致地更新, ...

  7. Java中的锁原理、锁优化、CAS、AQS详解!

    阅读本文大概需要 2.8 分钟. 来源:jianshu.com/p/e674ee68fd3f 一.为什么要用锁? 锁-是为了解决并发操作引起的脏读.数据不一致的问题. 二.锁实现的基本原理 2.1.v ...

  8. Java 中的锁原理、锁优化、CAS、AQS 详解!(转)

    1.为什么要用锁? 锁-是为了解决并发操作引起的脏读.数据不一致的问题. 2.锁实现的基本原理 2.1.volatile Java编程语言允许线程访问共享变量, 为了确保共享变量能被准确和一致地更新, ...

  9. Java 中的锁原理、锁优化、CAS、AQS 详解!

    来源:jianshu.com/p/e674ee68fd3f 1.为什么要用锁? 锁-是为了解决并发操作引起的脏读.数据不一致的问题. 2.锁实现的基本原理 2.1.volatile Java编程语言允 ...

随机推荐

  1. LeetCode专题-Python实现之第9题:Palindrome Number

    导航页-LeetCode专题-Python实现 相关代码已经上传到github:https://github.com/exploitht/leetcode-python 文中代码为了不动官网提供的初始 ...

  2. Java开发知识之Java的正则表达式

    目录 正则表达式 一丶什么是正则表达式 1.正则表达式简介 2.无正则表达式判断代码 3.使用正则表达式代码. 二丶正则表达式API 三丶正则表达式语法格式 1.正则表达式语法 正则表达式 一丶什么是 ...

  3. SpringBoot系列——i18n国际化

    前言 国际化是项目中不可或缺的功能,本文将实现springboot + thymeleaf的HTML页面.js代码.java代码国际化过程记录下来. 代码编写 工程结构 每个文件里面的值(按工程结构循 ...

  4. 第24章 退出 - Identity Server 4 中文文档(v1.0.0)

    注销IdentityServer就像删除身份验证cookie一样简单,但是为了完成联合注销,我们必须考虑将用户从客户端应用程序(甚至可能是上游身份提供者)中签名. 24.1 删除认证 要删除身份验证c ...

  5. 第一册:lesson 101。

    原文: A card from Jimmy Read Jimmy's card to me please,Penny. I have just arrive in Scotland and I'm s ...

  6. [PHP] yield沟通函数循环内外

    1.yield是函数内外,循环内外沟通用的 , 当你的函数需要返回一个大数组 , 循环的时候需要遍历这个大数组时 , 并且需要多次遍历这个函数的返回值 , 这个是有用的 2.当我也是只需要在一次循环中 ...

  7. (11)Microsoft office Word 2013版本操作入门_word中表格操作

    制作一个如下表格: 1. 插入一个4x4的表格或者手动绘制一个4x4表格. 1.1插入一个4x4表格或者绘制表格的按钮如下图所示 绘制表格,自己手动画比较复杂的表格 1.2对插入的表格:  点击表格的 ...

  8. 2013年第四届蓝桥杯javaB组 试题 答案 解析

    1.世纪末的星期 曾有邪教称1999年12月31日是世界末日.当然该谣言已经不攻自破. 还有人称今后的某个世纪末的12月31日,如果是星期一则会.... 有趣的是,任何一个世纪末的年份的12月31日都 ...

  9. Yii2基本概念之——配置(Configurations)

    在Yii中创建新对象或者初始化已经存在的对象广泛的使用配置,配置通常包含被创建对象的类名和一组将要赋值给对象的属性的初始值,这里的属性是Yii2的属性.还可以在对象的事件上绑定事件处理器,或者将行为附 ...

  10. JavaScript的工作原理:解析、抽象语法树(AST)+ 提升编译速度5个技巧

    这是专门探索 JavaScript 及其所构建的组件的系列文章的第 14 篇. 如果你错过了前面的章节,可以在这里找到它们: JavaScript 是如何工作的:引擎,运行时和调用堆栈的概述! Jav ...