首页 > 其他 > 详细

CAS compare and swap 比较并交换

时间:2020-04-21 17:02:39      阅读:73      评论:0      收藏:0      [点我收藏+]
public class CASDemo {
    public static void main(String[] args){
        AtomicInteger atomicInteger = new AtomicInteger(5);
        System.out.println(atomicInteger.compareAndSet(5,2019)+"\t current data: "+atomicInteger.get());
        System.out.println(atomicInteger.compareAndSet(5,1024)+"\t current data: "+atomicInteger.get());
    }
}

 

CAS的底层源码:

技术分享图片

  •  this;当前对象
  • valueOffset: 内存地址
  • expect:期待值
  • update:更新值

技术分享图片

 


Unsafe类:
是CAS的核心类,由于Java方法无法直接访问底层操作系统,需要通过本地方法来访问。Unsafe类相当于一个后门,基于该类可以直接操作特定内存的数据。Unsafe类在sun.misc包中,其内部方法操作可以像C的指针一样直接操作内存  
Unsafe类中的所有方法都是native修饰的(不对啊,很多方法明明没加native)
CAS并发原语体现在Java中就是Unsafe类中的各个方法。调用Unsafe类中的CAS方法,JVM会帮我们是先出CAS汇编指令。
这是一种完全依赖于硬件的功能,通过它实现了原子操作。
原语属于操作系统用语范畴,是由若干条指令组成的,用于完成某个功能的一个剁成,并且原语的执行必须是连续的,在执行过程中不允许被中断,也就是说CAS是一条CPU的原子指令,不会造成的数据不一致问题。

CAS的实现核心:
  • 自旋
  • unsafe类与内存值作比较。


Unsafe类的getAndAddInt()源码

技术分享图片

 

 

  • 参数列表:
  1. - var1 AtomicInteger本身
  2. - var2 变量var1的内存地址
  3. - var3
  4. - var4 值修改的量,比如加1的这个1
  5. - var5 通过内存地址找出的当前时间保存在这个位置上的值

 

  1. 方法执行过程:
  2. 取出地址上的值var5,并与var1比较(我感觉应该是var5和var2地址上的值比较,如果是var5和var1比较不久死循环了吗)
  3. 如果一致,说明没有被修改(这里先不考虑ABA问题)。就可以将var4+var5的值写到这个地址上,compareAndSwapInt()方法返回true,结束do-while循环
  4. 如果不一致,就继续执行do-while循环,这个循环称为自旋
  5. 问题:如果不一致,在这个方法里不是死循环了?
  6. 回答:不会,因为do-while的方法体里会读取一次var5,不可能一直死循环

 

    为什么用CAS而不用synchronized
   synchronized加锁,一致性得到保障,但是并发性下降,CAS既保证了一致性又保证了并发性 

   CAS的缺点
- 比较失败会一直尝试,如果长时间不成功,可能会给CPU带来很大的开销
- 只能保证一个共享变量的原子性,注意是一个。多个变量时就不能保证原子性了
- ABA问题

































CAS compare and swap 比较并交换

原文:https://www.cnblogs.com/cb1186512739/p/12745001.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!