前言:在对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. 全文检索-Elasticsearch (二) CURD

    ElasticSearch6.0以上版本的增删改查基本操作基于JSON的REST API与ElasticSearch进行通信.可以使用任何HTTP客户端来通信.当然ElasticSearch自己的文档 ...

  2. 自己构建一个Spring自定义标签以及原理讲解

    平时不论是在Spring配置文件中引入其他中间件(比如dubbo),还是使用切面时,都会用到自定义标签.那么配置文件中的自定义标签是如何发挥作用的,或者说程序是如何通过你添加的自定义标签实现相应的功能 ...

  3. AppBoxFuture(三): 分而治之

      系统数据量达到一定程度后必将采用分库分表的方式来提高系统性能,但传统的分库分表方式也必将带来更高的开发复杂程度.新一代的NewSql及NoSql数据库由于天生的分布式存储基因,既保证了能够横向扩展 ...

  4. Python迭代和解析(2):迭代初探

    解析.迭代和生成系列文章:https://www.cnblogs.com/f-ck-need-u/p/9832640.html 在Python中支持两种循环格式:while和for.这两种循环的类型不 ...

  5. .Net语言 APP开发平台——Smobiler学习日志:如何设置页面的title

    1.修改Mobile Form的TitleText的属性 输入需要显示标题,如图1: 2.修改Mobile Form的TitleStyle属性 其中包括Image属性(窗体图标).BackColor属 ...

  6. ROW_NUMBER() OVER()函数用法;(分组,排序),partition by

    转载:https://www.cnblogs.com/alsf/p/6344197.html 1.row_number() over()排序功能: (1) row_number() over()分组排 ...

  7. EF 批量 添加 修改 删除

    1批量添加    db.T_Investigator.AddRange(list) 2批量删除    db.T_Investigator.RemoveRange(list) 3批量修改   for 循 ...

  8. Linux-Kconfig总结与分析

    使用Kconfig时,需要注意的地方 1.在Kconfig中定义的配置宏,前缀都没有"CONFIG_",只有编译内核时,自动生成autoconf.h才会出现前缀. 2.如果XX_d ...

  9. Elasticsearch系列(4):基本搜索

    空搜索 搜索API的最基础的形式是没有指定任何查询的空搜索 ,它简单地返回集群中所有索引下的所有文档,如下命令: GET /_search 返回如下结果: 查询结果解释: 1,hits 返回结果中最重 ...

  10. jq筛选方法

    jq筛选方法(参照手册) 过滤: 1) eq(index|-index):获取第N个元素 负值表示从末尾开始匹配 <!-- 获取匹配的第二个元素 --> <p> This is ...