CAS问题

CAS是什么

(CAS知道吗?)

CAS的全称为Compare-And-Swap,它是一条CPU并发短语
它的功能是判断内存某个位置的值是否为预期值,如果是则更改为新的值,这个过程是原子的
CAS并发原语体现在Java语言中就是sun.misc.Unsafe类中的各个方法,调用UnSafe类中的CAS方法,JVM会帮我们实现出CAS汇编指令。这是一种完全依赖于硬件的功能,通过它实现了原子操作。再次强调,由于CAS是一种系统原语,原语属于操作系统用语范畴,是由若干条指令组成的,用于完成某一个功能的一个过程,并且原语的执行必须是连续的,在执行过程中不允许被中断,也就是说CAS是一条CPU的原子指令,不会造成所谓的数据不一致问题。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Co7WZqNh-1620402291798)(D:\ljwxy\陆君\笔记MD照片\多线程\CAS\Snipaste_2021-05-03_20-47-55.png)]

假设线程A和线程B两个线程同时执行getAndAddInt操作(分别跑在不同的CPU上)

  1. AtomicInteget里面的value原始值为3,即主内存中AtomicInteger的value为3,根据JMM内存模型,线程A和线程B各自持有一份值为3的value的副本分别到各自的工作内存。
  2. 线程A通过getIntVolatile(var1,var2)拿到value值3,这时线程A被挂起
  3. 线程B也通过getIntVolatile(var1,var2)方法获取到了value值3,此时刚好线程B没有被挂起并执行了compareAndSwapInt方法比较内存值也为3,成功修改内存值为4,线程B打完收工,一切OK
  4. 这时线程A恢复,执行compareAndSwapInt方法比较,发现自己手里的值数字3和主内存的值数字4不一致,说明该值已经被其他线程抢先一步修改过了,那A线程本次修改失败,只能重新读取重新来一遍了
  5. 线程A重新获取value值,因为变量value被volatile修饰,所以其他线程对它的修改,线程A总是能够看到,线程A继续执行compareAndSwapInt进行比较替换,知道成功

CAS得劣势

  • 循环开销很大:我们可以看到getAndInt方法执行时,有个do while,如果CAS失败,会一直进行尝试,如果CAS长时间一直不成功,可能会给CPU带来很大得开销
  • 只能保证一个共享变量得原子操作:当对一个共享变量执行操作时,我们可以使用循环CAS得方式来保证原子操作,但是对多个共享变量操作时,循环CAS就无法保证操作得原子性,这个时候就可以用锁来保证原子性
  • 引发出来ABA问题

ABA是什么

(原子类AtomicInteger得ABA问题谈谈?原子更新引用知道吗?)

ABA:就是线程A修改过一个数据,不过在进行多次修改过后,有修改成了原数据,此时线程B接手,发现预算值和内存的值一致,但是已经多次操作了。

CAS——>UnSafe——>CAS底层思想——>ABA——原子引用更新——>如何规避ABA问题

//支持时间戳得普通原子引用
static AtomicReference<Integer> atomicReference = new AtomicReference<>(100);
//                             100:初始数据  1:初始版本 就时依靠版本来解决ABA问题得
static AtomicStampedReference<Integer> atomicStampedReference=new AtomicStampedReference<>(100,1)

=new AtomicStampedReference<>(100,1)


在每次修改数据得时候 不光要判断数据是否一致,还要判断版本号是否一致,版本号也一致 才算成功。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值