概念

CAS(Compare And Swap 比较并交换),是 乐观锁 的一种典型实现机制。

乐观锁主要的两个步骤:冲突检测、数据更新。

当多个线程尝试使用CAS同时更新通过一个变量的时候,只有一个线程可以更新变量的值,其他线程都会失败,失败的线程不会被挂起,而是告知失败并可以再次尝试。

CAS操作包括3个操作数:需要读写的内存位置(V)、预期原值(A)、新值(B)。

如果内存位置与预期原值的A匹配,那么内存位置会更新为新值B;

如果内存位置与预期原值的值不匹配,那么处理器不会做任何操作;

无论何种情况,它都会在CAS指令之前返回该位置的值。

缺陷

1.ABA问题

现有一个单向链表实现的堆栈,栈顶为A,A.next为B

线程one希望通过CAS将栈顶A替换为B:head.compareAndSet(A, B); 执行此命令前,线程two介入,将A,B出栈,然后push D、C、A,此时栈结构如下:

对象B此时处于游离状态,轮到线程one执行CAS操作,检测发现栈顶仍为A,所以CAS成功,栈顶变成B,但是实际上B.next 是null,所以这时的情况为:

   

解决方法:而B成为了只有1个元素的堆栈,C和D组成的链表就不再存在于此堆栈中,也就是被丢掉了。

jdk 1.5开始atomic包提供了类AtomicStampedReference来解决ABA问题。

AtomicStampedReference的compareAndSet方法首先就检测当前引用是否等于预期引用,并且当前标志是否等于预期标志,如果全部相等,则以原子的方式将该引用和该标志的值设置给指定的更新值。

2.循环时间长开销大

自旋CAS(不成功,就一直循环执行,直至成功)如果长时间不成功,会给CPU带来极大的开销。

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

当只对1个变量执行操作时,可以使用循环CAS的方式保证原子操作,但是多个共享变量操作时,循环CAS就无法保证操作的原子性。

解决方法可以使用锁,但也有一个取巧的方法,就是多个共享变量合并成1个共享变量操作。

CAS简介的更多相关文章

  1. CAS 之 Apereo CAS 简介(一)

    CAS 之 Apereo CAS 简介(一) Background(背景) 随着公司业务的不断扩展,后台接入子系统不断增多,那么我们将针对不同的平台进行拆分为各自对应的子系统, 权限是不变的,那么我们 ...

  2. CAS简介和无锁队列的实现

    Q:CAS的实现 A:gcc提供了两个函数 bool __sync_bool_compare_and_swap (type *ptr, type oldval, type newval, ...)// ...

  3. 单点登录之CAS简介

    cas官网http://www.ja-sig.org/products/cas/. ok,如今開始本文的重点内容解说,先来了解一下cas 实现single sign out的原理,如图所看到的:    ...

  4. 并发和多线程(二)--线程安全、synchronized、CAS简介

    线程安全性: 当多个线程访问一个类的时候,这个类始终表示出正确的行为,那么这个类是线程安全的. 无状态的对象一定是线程安全的,例如大部分service.dao.Servlet都是无状态的. 线程安全体 ...

  5. Cas简介(一)

    Cas的全称是Centeral Authentication Service,是对单点登录SSO(Single Sign On)的一种实现.其由Cas Server和Cas Client两部分组成,C ...

  6. CAS单点登录系统简介

    一.cas简介 全名:Central Authentication Service特点: 1.开源的.多协议的 SSO 解决方案: Protocols : Custom Protocol . CAS ...

  7. CAS学习笔记(一)

    近期做单点登录,看了一些CAS资料,做下总结 一.cas简介 全名:Central Authentication Service 特点: 1.开源的.多协议的 SSO 解决方案: Protocols  ...

  8. CAS实现SSO单点登录原理

    1.      CAS 简介 1.1.  What is CAS ? CAS ( Central Authentication Service ) 是 Yale 大学发起的一个企业级的.开源的项目,旨 ...

  9. 单点登录系统CAS筹建及取得更多用户信息的实现

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...

随机推荐

  1. 函数指针和qsort函数

    1.函数指针的形式: 函数指针:int (*funcP) (int *a, int *b) 表示定义了一个funcP函数指针,指向了返回值为int类型,参数为int* 和int* 的函数 使用方式: ...

  2. [hi3521] nand flash 的 boot 启动模式的区别?

    spi nand flash 的 boot 启动模式选择.0:1 线 boot:1:4 线 boot.请问,1线boot和4线boot有什么区别呢?该如何选择呢?     收藏 顶 踩   回复 使用 ...

  3. AOP源码解析:AspectJAwareAdvisorAutoProxyCreator类的介绍

    AspectJAwareAdvisorAutoProxyCreator 的类图 上图中一些 类/接口 的介绍: AspectJAwareAdvisorAutoProxyCreator : 公开了Asp ...

  4. Spring IOC:BeanDefinition加载注册流程(转)

    BeanFactory接口体系 以DefaultListableBeanFactory为例梳理一下BeanFactory接口体系的细节 主要接口.抽象类的作用如下: BeanFactory(根据注册的 ...

  5. OKhttp3的使用教程

    首先在build.gradle下的dependencies下添加引用. implementation "com.squareup.okhttp3:okhttp:4.9.0" 然后编 ...

  6. Luogu P1525 [NOIp2010提高组]关押罪犯 | 并查集

    题目链接 这一道题,我用了并查集来做.在此题中,并查集的作用就是:将同一个监狱里的罪犯合并到一起. 思路:将每对罪犯之间的怨气值从大到小排序,再依次把他们分到不同的两个监狱里,当发现这一对罪犯已经在同 ...

  7. CentOS7 导入oracle数据

    1.切换到 oracle用户 #su - oracle 2.导入(一般的不会导入到sys账号下) #imp sys/密码@orcl file=/home/oracle/20200428.dmp fro ...

  8. Java——去掉小数点后面多余的0

    当小数点后位数过多,多余的0没有实际意义,根据业务需求需要去掉多余的0.后端存储浮点型数据一般会用到Bigdecimal 类型,可以调用相关方法去掉小数后多余0,然后转为string. public ...

  9. silky微服务框架服务注册中心介绍

    目录 服务注册中心简介 服务元数据 主机名称(hostName) 服务列表(services) 终结点 时间戳 使用Zookeeper作为服务注册中心 使用Nacos作为服务注册中心 使用Consul ...

  10. filter筛选数组

    和map()类似,array的filter也接收一个函数 和map()不同的是,filter把传入的函数依次作用于每个函数,然后根据返回TRUE还是FALSE来做决定保留还是舍弃该元素 例如,删除一个 ...