CAS的全称是CompareAndSwap,比较并交换,是Java保证原子性的一种重要方法,也是一种乐观锁的实现方式。

它需要先提前一步获取旧值,然后进入此方法比较当下的值是否与旧值相同,如果相同,则更新数据,否则退出方法,重复一遍刚才的动作。由此可见,CAS方法是非堵塞的。CAS方法需要三个参数,变量内存值、旧的预期值、数据更新值

CAS的伪代码可以表示为:

do{

  获取备份旧数据;

  准备更新的数据;

}while( !CAS( 内存地址,备份的旧数据,新数据 ))


private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;
    /**
* Atomically sets the value to the given updated value
* if the current value {@code ==} the expected value.
*
* @param expect the expected value
* @param update the new value
* @return {@code true} if successful. False return indicates that
* the actual value was not equal to the expected value.
*/
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}

上面是原子类AtomicInteger的局部源码,可以看出来Java中的CAS操作都是由Sun包下的Unsafe类实现的,而unsafe类中的方法都是Native方法,都是由JVM本地实现。

然后简单去网上找了找相关的openJDK源码,它调用了Atomic:comxchg方法,这个方法的实现放在了hotspot下的os_cpu包中的,也就是说它调用了操作系统和CPU层级的东西。

经过进一步了解获知,这个方法在Linux x86系统的多处理器情况下是通过调用LOCK指令来实现的,立刻写会内存且令其他缓存行失效。


CAS的问题:

1、ABA问题,比如刚开始读取到备份是3,然后被其他线程连续修改两次,最终结果还是3,那么CAS很可能识别不到数据发生了改变,这种情况对程序造成了极大的安全隐患。可以通过添加版本号等标志位来解决该问题。

2、循环时间长开销大,如果长时间自旋不成功,会给CPU带来很大开销。可以使用自适应自旋锁解决这个问题

3、只能保证一个共享变量的原子操作。比如AtomicInteger都是每次只能对一个变量进行原子性控制。


单次CAS操作的开销:

这是一个8核CPU的计算机系统,先简单介绍一下CPU的硬件结构体系。每个CPU都有一个高速缓存区Cache(寄存器),每两个CPU之间有一段互联模块可以让管芯内的两个核可以互相通信,最中间还有个系统互联模块可以让四个管芯进行通讯。数据以“缓存线”为单位在系统中传输,缓存线对应内存中2的整数幂的一个字节块

计算机系统中,当CPU要获取一个变量值的时候,必须要将包含了该变量的缓存线保存到自己的寄存器中;CPU要向主存写入值的时候,根据缓存一致性协议,必须保证其他CPU获知此操作,或者让其他CPU删除该缓存线的拷贝。

因此,如果CPU1和CPU5同时持有一个变量的缓存线,然后CPU5想进行CAS操作,那么它需要访问CPU5、6的互联模块,未找到持有该缓存线的CPU,然后访问系统级的互联模块,发现第一处互联模块有该缓存线,继而访问第一处互联模块,最终找到了CPU1。此时才算是完成了大部分操作。因此如果从最优角度考虑,CAS所花费的时钟周期较锁来说要小很多。

在Java中,sun.misc.Unsafe类提供了硬件级别的院子操作来实现这个CAS,JUC包下的大量类都使用了这个Unsafe.java类的CAS操作。

CAS的实现原理的更多相关文章

  1. Java CAS同步机制 原理详解(为什么并发环境下的COUNT自增操作不安全): Atomic原子类底层用的不是传统意义的锁机制,而是无锁化的CAS机制,通过CAS机制保证多线程修改一个数值的安全性。

    精彩理解:  https://www.jianshu.com/p/21be831e851e ;  https://blog.csdn.net/heyutao007/article/details/19 ...

  2. (转载)java高并发:CAS无锁原理及广泛应用

    java高并发:CAS无锁原理及广泛应用   版权声明:本文为博主原创文章,未经博主允许不得转载,转载请注明出处. 博主博客地址是 http://blog.csdn.net/liubenlong007 ...

  3. CAS单点登录原理以及debug跟踪登录流程

    CAS 原理和协议 基础模式 基础模式 SSO 访问流程主要有以下步骤: 1. 访问服务: SSO 客户端发送请求访问应用系统提供的服务资源. 2. 定向认证: SSO 客户端会重定向用户请求到 SS ...

  4. Springboot security cas整合方案-原理篇

    前言:网络中关于Spring security整合cas的方案有很多例,对于Springboot security整合cas方案则比较少,且有些仿制下来运行也有些错误,所以博主在此篇详细的分析cas原 ...

  5. CAS单点登录原理简单介绍

    1. SSO简介 1.1 单点登录定义 单点登录(Single sign on),英文名称缩写SSO,SSO的意思就是在多系统的环境中,登录单方系统,就可以在不用再次登录的情况下访问相关受信任的系统. ...

  6. CAS单点登录原理解析

    转自: https://www.cnblogs.com/lihuidu/p/6495247.html 1.基于Cookie的单点登录的回顾        基于Cookie的单点登录核心原理: 将用户名 ...

  7. CAS单点登录原理

    转自 https://www.cnblogs.com/lihuidu/p/6495247.html 1.基于Cookie的单点登录的回顾        基于Cookie的单点登录核心原理: 将用户名密 ...

  8. CAS单点登录原理解析(转载)

    1.基于Cookie的单点登录的回顾        基于Cookie的单点登录核心原理: 将用户名密码加密之后存于Cookie中,之后访问网站时在过滤器(filter)中校验用户权限,如果没有权限则从 ...

  9. CAS 跨域原理

    http://www.blogjava.net/rain1102/articles/227739.html CAS(Central Authentication Service) 是 Yale 大学发 ...

  10. 解决并发问题的CAS思想及原理

      全称为:Compare and swap(比较与交换),用来解决多线程并发情况下使用锁造成性能开销的一种机制:   原理思想:CAS(V,A,B),V为内存地址,A为预期原值,B为新值.如果内存地 ...

随机推荐

  1. [学习笔记]整体DP

    问题: 有一些问题,通常见于二维的DP,另一维记录当前x的信息,但是这一维过大无法开下,O(nm)也无法通过. 但是如果发现,对于x,在第二维的一些区间内,取值都是相同的,并且这样的区间是有限个,就可 ...

  2. SQL 变量,运算符

    一.变量 SQL语言也跟其他编程语言一样,拥有变量.分支.循环等控制语句. 在SQL语言里面把变量分为局部变量和全局变量,全局变量又称系统变量. (一).局部变量 使用declare关键字给变量声明, ...

  3. gSOAP 使用

    1. wsdl2h 生成服务定义头文件 wsdl2h -o calc.h http://www.genivia.com/calc.wsdl 2. 从服务定义头文件calc.h生成客户端代码 soapc ...

  4. H3C HDLC状态检测

  5. PHP IF判断 简写

    第一种:IF 条件语句 第二种:三元运算 第三种:&& .|| 组成的条件语句 第一种: IF 基础,相信绝大多数人都会: 第二种:  c=a>b ? true:false  / ...

  6. 配置gitignore后使其生效命令

    改动过.gitignore文件之后,在repo的根目录下运行: git rm -r --cached . git add . 之后可以进行提交: git commit -m "fixed u ...

  7. linux清理函数

    每个非试验性的模块也要求有一个清理函数, 它注销接口, 在模块被去除之前返回所有资 源给系统. 这个函数定义为: static void   exit cleanup_function(void) { ...

  8. vue element UI el-table 表格调整行高的处理方法

    这是我在工作项目中遇到的问题,我想将标记处下方的表格高度调低一点,也就是想实现下面的这个效果: 代码调整如下: 说明: 缩小:行高到一定程度之后便不能缩小. 好像最小35px.各位可以试一下. 升高: ...

  9. H3C进入目录---用户视图

    进入logfile文件目录 <H3C>cd logfile/        //进入目录 <H3C>pwd             //显示当前所属的目录 cf:/logfil ...

  10. Oracle 和pl/sql以及pl/sql developer

    oracle是厂家的名字,也是数据库产品的名字.比如sybase公司的sybase数据库.而微软公司的数据库产品就叫sqlserver了. pl/sql 是oracle数据库所用的sql语言的名称.微 ...