zoukankan      html  css  js  c++  java
  • cas机制的原理和使用

    一、什么是cas

      CAS,compare and swap的缩写,中文翻译成比较并交换。

      CAS 操作包含三个操作数 —— 内存位置(V)、预期原值(A)和新值(B)。 如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值 。否则,处理器不做任何操作。

      从思想上来说,Synchronized属于悲观锁,悲观地认为程序中的并发情况严重,所以严防死守。CAS属于乐观锁,乐观地认为程序中的并发情况不那么严重,所以让线程不断去尝试更新。

    二、原子操作类

      从JDK 1.5开始提供了java.util.concurrent.atomic包,在该包中提供了许多基于CAS实现的原子操作类,用法方便,性能高效,例如

      AtomicBoolean:原子更新布尔类型

      AtomicInteger:原子更新整型

      AtomicLong:原子更新长整型

    三、cas的缺点

    1.CPU开销较大

    在并发量比较高的情况下,如果许多线程反复尝试更新某一个变量,却又一直更新不成功,循环往复,会给CPU带来很大的压力。

    2.不能保证代码块的原子性

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

    3.ABA问题

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

    四、ABA问题的原理和解决

      假设这样一种场景,当第一个线程执行CAS(V,E,U)操作,在获取到当前变量V,准备修改为新值U前,另外两个线程已连续修改了两次变量V的值,使得该值又恢复为旧值,这样的话,我们就无法正确判断这个变量是否已被修改过,如下图
      
      这就是典型的CAS的ABA问题,一般情况这种情况发现的概率比较小,可能发生了也不会造成什么问题,比如说我们对某个做加减法,不关心数字的过程,那么发生ABA问题也没啥关系。但是在某些情况下还是需要防止的,那么该如何解决呢?在Java中解决ABA问题,我们可以使用以下两个原子类


    AtomicStampedReference
      AtomicStampedReference原子类是一个带有时间戳的对象引用,在每次修改后,AtomicStampedReference不仅会设置新值而且还会记录更改的时间。当AtomicStampedReference设置对象值时,对象值以及时间戳都必须满足期望值才能写入成功,这也就解决了反复读写时,无法预知值是否已被修改的窘境


    AtomicMarkableReference
      AtomicMarkableReference与AtomicStampedReference不同的是,AtomicMarkableReference维护的是一个boolean值的标识,也就是说至于true和false两种切换状态,经过测试,这种方式并不能完全防止ABA问题的发生,只能减少ABA问题发生的概率。

    参考:https://blog.csdn.net/mmoren/article/details/79185862

    https://mp.weixin.qq.com/s?__biz=MzIxMjE5MTE1Nw==&mid=2653192625&idx=1&sn=cbabbd806e4874e8793332724ca9d454&chksm=8c99f36bbbee7a7d169581dedbe09658d0b0edb62d2cbc9ba4c40f706cb678c7d8c768afb666&scene=21#wechat_redirect

     

  • 相关阅读:
    10.16(day54)
    10.17(day55)
    10.15(day53)
    10.14(day52)
    10.12(day51)
    10.11(day50)form表单,css的引入,css选择器,css修改字体属性
    10.10(day49)初识前端,html基础
    9.25(day44)
    9.24(day43)
    9.23(day42)数据库的配置,数据库表的引擎,数据类型,约束条件
  • 原文地址:https://www.cnblogs.com/JavaZhangXu/p/10044132.html
Copyright © 2011-2022 走看看