美文网首页
(十七)CAS

(十七)CAS

作者: hedgehog1112 | 来源:发表于2020-10-21 11:44 被阅读0次

    比较并交换:通常指CompareAndSwap或CompareAndSet,乐观锁

    1、CAS是一个原子操作比较内存位置值且相等时修内存位置值为新值,保证新值总基于最新信息计算,如其他线程期间修改这个值则CAS失败。CAS返回是否成功或者内存位置原来的值用于判断是否CAS成功。

    2、JVM中的CAS操作是利用了处理器提供的CMPXCHG指令实现的。

    优点:竞争不大时系统开销小

    缺点:1)循环时间长开销大。2)ABA问题。3)只能保证一个共享变量原子操作

    一、AtomicInteger(原子性的更新和比较值)

    1、自增方法 incrementAndGet:

    CAS的自旋。无限循环:1)获取当前值2)当前值+1 = 目标值。3)CAS操作,成功跳出,失败重复上述。

    2、compareAndSet

    一行代码。两个对象:

        unsafe:直接接访问底层操作系统的“后门”,提供硬件级别原子操作:保证Compare和Swap之间原子性操作

        valueOffset:AtomicInteger对象value成员变量在内存中的偏移量。value变量内存地址。unsafe.objectFieldOffset方法得到,

    二、ABA

    3个基本操作数:内存地址V(valueOffset),旧值A,新值B

    内存中有:值为A的变量,存在地址V中。三个线程想用CAS方式更新A:

    1)线程1、2已获得当前值,3还未

    2)1先一步成功,A更新为B2被阻塞,没更新;3在1后,获得B

    3)3更新为A、2恢复,阻塞前已获A,compare检测,内存地址V中也是A,把A更新成B

    例:100元存款,提50元,提款机出问题,同时提交两次,两个线程都是获取100元,要更新成50元。

    理想情况下,一个成功,另一失败,扣一次。

    2)1成功,100成50。2阻塞。这时,妈刚汇503成功,50改成100

    3)2恢复,已经获“当前值”100,compare检测,也是100,100更新成50。

    解决办法:AtomicStampedReference用版本号做比较CAS机制:Compare操作。线程1获得值和地址V都是A,但版本号不相等,更新失败。

    https://mp.weixin.qq.com/s/nRnQKhiSUrDKu3mz3vItWg

    相关文章

      网友评论

          本文标题:(十七)CAS

          本文链接:https://www.haomeiwen.com/subject/ngddmktx.html