volatile关键字

     volatile是java中的关键字,主要保证了变量的可见性和有序性。说到这个我们就需要了解一下jvm的内存模型jmm

     jvm内存:主内存(计算机物理内存)+工作内存(高速缓存区):


   1.线程在工作内存获取变量值

   2.工作内存获取主内存的值

   3.修改后,存储在工作内存中

   4.工作内存刷新数据到主内存中

注:当两个线程同时对一个共享变量操作时:例如:i=1

      A线程获取i=1  拿到工作内存

      B线程获取i=1  拿到工作内存

      A线程执行i+1操作  此时i=2  然后刷新到主内存

      B线程执行i+1操作  此时i=2  然后刷新到主内存

最终主内存中i=2

但是我们其实想要的正确结果是3。

上面说到的这个情况就是多线程并发导致的问题,我们知道在并发编程中,保证请求正确数据正确有3个原则:原子性,可见性,有序性

  原子性:不可分割,也就是说不能分开执行,执行过程不可被打断。举个例子:项目中所说的事务就必须具备原子性。

  可见性:当一个线程修改某个共享变量的值时,对于其他线程来说是立马可见的。

  有序性:代码的执行顺序是有序的,不可改变的。

而volatile关键字就保证了可见性和有序性,但是不能保证原子性。

volatile主要操作的是共享变量:类的成员变量,类的静态变量

    可见性:保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。

   有序性:修饰的变量不可被指令重排,保证有序性。

    1)当程序执行到volatile变量的读操作或者写操作时,在其前面的操作的更改肯定全部已经进行,且结果已经对后面的操作可见;在其后面的操作肯定还没有进行;

   2)在进行指令优化时,不能将在对volatile变量访问的语句放在其后面执行,也不能把volatile变量后面的语句放到其前面执行

volatile原理和实现机制:

   主要是利用了内存屏障来做的处理;

    1)它确保指令重排序时不会把其后面的指令排到内存屏障之前的位置,也不会把前面的指令排到内存屏障的后面;即在执行到内存屏障这句指令时,在它前面的操作已经全部完成;

    2)它会强制将对工作缓存的修改操作立即写入主内存;

    3)如果是写操作,它会导致其他CPU中对应的缓存行无效。

volatile使用场景:

   为了满足并发三要素,一般对于共享资源我们都会采用synchronized关键字来处理,但是synchronized效率比较低,相当于是悲观锁意思,而且需要线程的上线文切换,在一些业务场景,使用volatile也可以达到效果,并且执行效率会高一些。

   使用volatile修饰的变量一般必须满足下面两个条件:

   1)对变量的写操作不依赖与变量的当前值

   2)该变量不能被包含着有其他变量的不变式中(不参与与其他变量的计算)

   所以这两个条件的意思也就是必须要保证原子性才可以,在使用volatile的时候保证程序的正确性。

一般用在状态的标记。

   

     

    

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值