java cas volatile_Volatile&CAS浅析

Volatile关键字

先了解一个概念JMM内存模型图:

1d14901a319dee5a33184a36bb7cdff6.png

每个线程在操作的时候都会有一个属于自己的工作内存(即上图中的本地内存),这些工作内存存在的变量都是从主物理内存(即上图的主内存)拿到的,那么在进行更改的时候,需要在本地工作内存先进行操作,之后再写到主物理内存,其他线程再去取主物理内存中的值,确保数据在每个线程都是可见的,这个时候可能会有人有疑问为什么不直接在主物理内存操作,原因就是主物理内存并不能直接操作,不然也不会要有本地工作内存在,需要注意的是JMM模型并不真实存在,只是人们想象出来的一个模型

正文

你可以理解为这是一个轻量级的synchronized, volatile关键字可以保证可见性,有序性,需要注意的是volatile关键字并不能保证原子性,可以禁止指令重排,通常用于并发编程,何为原子性,就是某一个线程在进行某个业务操作时,不可分割,要么同时成功,要么同时失败,可以使用原子类(如:AtomicInteger)来解决volatile不具备原子性的问题。何为指令重排,java底层在进行编译代码的时候,会进行指令重排,计算机底层在执行代码的时有时候并不会按你写的代码顺序走,为了性能它可能会重新排序,但是一切都得遵循数据依赖性原则(就是要重新排序的东西得先确保定义了这个东西),详细见下:

7be812f57a6228a8b2022edfe2b3177f.png

8f4e729d82008ed1a05f528889047fde.png

具体代码示例会出现的情况:

8c939db658899118e58f944f6f576e87.png

CAS

全称Compare-And-Swap,是CPU的一条并发原语,具体功能判断内存某个位置的值是否被改过,如果是则更新新的值,整个过程是原子性的,底层是Unsafe类,CAS并发原与在Java中的体现就是Unsafe类下的各个方法,强调一下,由于CAS是系统一种系统原语,属于系统用语范畴,是由若干条命令组成的,用于完成某个功能的一个过程,并且原语的执行必须是连续的,在执行过程中不允许被中断,也就是说CAS是一条CPU的原子指令,不会造成所谓的数据不一致的问题。Unsafe下的所有方法都是native修饰的,也就是说直接操作底层操作系统资源执行响应任务的

应用:

CAS中有三个值,内存值V,旧的预期值A,要更改的值B

当且仅当A等于V时,将V修改为B,否则什么都不做,可以运用Atomic类来实现,如图所示:

eec4cd028f3c719310a53a77834a5a86.png

CAS的方法其实是一个自旋锁,当条件成立的时候,他就跳出循环,没有成立期间,会一直进行自旋,如图所示:

3c2e54d2bfcf736a938c1d1d560b12b1.png

人无完人,世间万物都是一个道理,即使说得CAS这么好,他也是有缺点的,就是想想,如果一直跳不出循环的话,会怎么样?对!会对CPU造成巨大的压力

882acc7d0824bfdeba583f0c099b0008.png

那么说到这里,就不得不提到一个所谓的ABA问题了,何为ABA,听我慢慢跟你说

faa45eef1292e8f22db5bc848be2a8d1.png

假设这个时候现在有两个线程,线程1和线程2(下面简称1,2),1是10秒钟执行一次线程,2是2秒钟执行一次线程,那么10秒的时间2是可以执行5次,显而易见,2比1速度快,那么此时2从主物理内存去拿值,值A,2从自己的工作内存将A修改为B,但是后来2脑子抽风了,又把B修改成了A,此时,1再去取主物理内存中的值,看起来是一样的,顺利拿到值A,但是实际上已经被2改过好几次了,1是毫不知情的,虽然结果没有变化,但是会带来什么后果呢?想想,一个小偷,把别人家的钱偷了之后又还了回来,还是原来的钱吗,你老婆出轨之后又回来,还是原来的老婆吗?ABA 问题也一样,如果不好好解决就会带来大量的问题。最常见的就是资金问题,也就是别人如果挪用了你的钱,在你发现之前又还了回来。但是别人却已经触犯了法律。如图所示:

dfe1ded74fea89cc056965749a938c51.png

那当然问题出现了,就会有结局问题的办法,如何解决ABA问题呢,在修改值的时候加上版本号即可:

96477ec7b7ba4bc63b4b4037ff38cfce.png

359bb7456d7e4f7a2def6370bd02a9e7.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值