1. 什么是CAS?

    Compare and Swap (比较交换),使用CAS来保证线程的对变量的原子操作,避免被其他线程所干扰。

  2. CAS原理:其中包含三个参数

    1. 要修改的变量

    2. 变量的预期值

    3. 要更性的参数

      在更新数据时,CAS先判断变量中的值与预期值,如果一致则更新为新值,如果变量的值与预期值不 一致,表示当前操作被其他线程干扰,此时线程不会阻塞而是自旋等待(自旋锁),重复以上操作,CAS操作即 使没有锁,也可以发现其他线程对当前线程的干扰,并进行恰当的处理。

      CAS在Java层面虽然没有使用锁保证原子性,但是在底层汇编对“比较替换”进行加锁保证其原子性操作。

    4. CAS可能存在的问题

      1. CPU开销较大

        在并发较高的情况下,如果许多线程反复尝试更改一个变量,却一直更新不成功,循环往复,会给CPU带来很大压力。看可以通过设置默认自旋次数来减少CPU消耗。

      2. 不能保证代码原子性

        CAS机制所保证的只是一个变量的原子性操作,而不能保证整个代码块的原子性。比如需要保证3个变量共同进行原子性的更新,就不得不使用synchronized了。

      3. ABA问题

        这是CAS机制存在的最大的问题。

  3. ABA问题

    什么是ABA问题?

    -在使用CAS进行变量的原子性操作时,先要获取一个预期值,然后再判断预期值与实际的值是否相同,如果相同则继续修改变量。由于CAS操作没有使用重量级锁,如果获得一个预期值后,实际的值被其他线程篡改为其他值,然后又被改回到原有的值,对于原线程来说,实际值和预期值是一样的,但实际上值已经被修改过。这样的问题就是ABA问题

    例如:t1线程进行CAS操作,获取的预期值为"A",在t1线程进行"比较交换"前,t2线程进入并将变量的值 由"A"改为"B",然后又重新改回到"A"并退出,此时对于t1线程来说,实际值和预期值都是"A",就可以 做"比较并交换"操作,但实际上,实际值"A"已被修改过。

  4. 如何解决ABA问题

    上述例子看似没有问题,但是结合实际就会发现其问题所在,举例如下:

    ,假设有一个遵循CAS的取款机,小明去取款机取款,此使账户余额100元,小明要取款50,但是由于故障取款机执行了两次取款线程:

    • 线程1:取款50,余额50

    • 线程2:取款50,余额50(失败)

      理想状况下之只能有一个线程执行成功,另一个线程执行失败,进入等待,但是此时小明的母亲给小明转账50元,此时:

    • 线程3:存款50,余额100元

      由于线程3执行成功,小明账户余额又到达了100元,此时线程2,通过cas比较交换,发现前后数据一致,所以可以进行数据改写.如下:

    • 线程2:取款50,余额50

      此时不难发现小明的余额少了50元.这就是ABA问题.那么我们如何解决呢?

    • 我们可以使用CAS中的"原子引用"来解决ABA问题.

      原子引用是基于乐观锁的思想,为CAS中的每个操作添加一个版本号,每次执行成功之后,都会对版本号进行+1操作,每次更新数据之前都会对比版本号,观察是否有其他线程进行干扰.如果版本号一制则继续,不一致进入自旋.

      Java中提供了AtomicStampedReference类来实现原子引用并可以设置版本号

CAS中ABA问题的解决相关推荐

  1. 18.AtomicReference、AtomicStampReference底层原理。多个变量更新怎么保证原子性?CAS的ABA问题怎么解决?

    老王:小陈啊,上一章我们说了AtomicInteger.AtomicBoolean的底层原理,这一篇我们就来说说Atomic系列的另一个分类AtomicReference和AtomicStampRef ...

  2. CAS的ABA问题及解决代码示例

    1.ABA问题示例 package com.example.sgg.juc;import java.util.concurrent.TimeUnit; import java.util.concurr ...

  3. java购买同一件商品时加锁_java中CAS的ABA问题思考和整理(不看后悔系列)

    前言 听说经常面试被问到~今天同事说了这个问题,就查了一下这问题,觉得挺有意思的,就整理出来跟大家分享下.主要思考下面几个问题: 1.什么是CAS? 2.什么是CAS的ABA问题? 3.怎么解决这个问 ...

  4. CAS详解及ABA问题的解决

    序言 由于最近项目上遇到了高并发问题,而自己对高并发,多线程这里的知识点相对薄弱,尤其是基础,所以想系统的学习一下,以后可能会出一系列的JUC文章及总结 ,同时也为企业级的高并发项目做好准备. 本文是 ...

  5. CAS中的ABA问题

    文章目录 1.什么是ABA问题 2.解决ABA问题 如果不理解CAS操作,可以看看我之前写的博客----CAS操作的基本原理 1.什么是ABA问题 CAS中的关键,就是先用内存中的值和旧的预期值进行比 ...

  6. JUC04-- CAS自旋 、CAS自旋锁、ABA问题及解决办法、18大原子类

    文章目录 JUC04 课程任务概览 CAS CAS原理简介 CAS发展: CAS是什么? CAS原理: CAS优点: **CAS底层实现-引出Unsafe类** ==CAS自旋实现个人总结== Ato ...

  7. cas引出的ABA问题?如何解决?- 理解原子引用、时间戳(版本号)原子引用

    ABA问题: 假如有两个线程1,2: cas下:1.线程取值完等待,2线程取值并把A改成B,有把B改成A,这是1线程执行会任务A还是原来的A没有发生改变,如果不在乎中间结果,只看收尾,那么没必要解决A ...

  8. AtomicStampedReference解决CAS的ABA问题

    AtomicStampReference 解决CAS的ABA问题 什么是ABA ABA问题:指CAS操作的时候,线程将某个变量值由A修改为B,但是又改回了A,其他线程发现A并未改变,于是CAS将进行值 ...

  9. mysql解决aba问题_AtomicStampedReference解决CAS的ABA问题

    AtomicStampReference > 解决CAS的ABA问题 什么是ABA > ABA问题:指CAS操作的时候,线程将某个变量值由A修改为B,但是又改回了A,其他线程发现A并未改变 ...

最新文章

  1. wxWidgets:wxDynamicLibrary类用法
  2. Android-滑动解锁高亮文字自定义TextView
  3. 栈大小和内存分部问题
  4. 中国区块链开发者的热血时代来临!
  5. redis重做从库时报Connection with master lost错误
  6. Word给自动生成的目录页码添加括号
  7. 三分钟彻底弄明白shiro原理
  8. 用户流失生命周期如何最大化延缓或延长(包含引流-促活-问卷调研-流失召回话术)
  9. 等差数列_等比数列公式
  10. SpringBoot 项目鉴权的 4 种方式
  11. domian shift
  12. SSD固态硬盘怎么选?选对接口是关键
  13. solidity的函数修改器(modifier)
  14. Dubbo(Spring配置)
  15. C语言现行标准C11的新特性
  16. 搜索某个网段内所有在线IP的一串命令
  17. 真相了:大众创业葬送了多少人的前程?
  18. springboot请求注解的使用Get/Post
  19. 手机中geetest是什么文件_安卓文件隐藏精灵 — 隐藏手机中的小秘密
  20. 判断2064年是不是闰年。 闰年判断规则: 能被400整除的是闰年( 2000年是闰年) 能被4整除,不能被100整除的是闰年(2004年是闰年) 其他的不是闰年(1900年不是闰年)

热门文章

  1. 利用Matlab读取Excel数据并进行拟合
  2. Sourcemap 配置详解
  3. OSChina 周日乱弹 —— 让人热血沸腾的女人
  4. Changers发布149美元移动社交太阳能充电系统并接受预定
  5. Base64与Java -- Base64简介与原理
  6. 拿出咱家的家当来和你秀一秀
  7. M1上模拟器无法运行的项目,可以用Rosetta打开
  8. 失传的C结构体打包技艺 -- 内存对齐
  9. react 进阶必学 hook (一):useState 来一碗大碗宽面
  10. vue 使用gojs绘制简单的流程图