volatile关键字的用法

        volatile关键字是在并发编程中使用频率非常高的一个关键字,那么volatile关键字到底有什么作用呢?根据官方的定义,volatile关键字主要有2个作用,保持变量在内存中的可见性和禁止指令重排序,下面就这2个用法进行详细的说明。

一、保持变量在内存中的可见性

       要理解这句话首先要明白线程是怎么工作的,jvm运行时会给变量分配一个内存,我们可以称之为主内存,每一个线程运行时都会有一个线程栈,线程栈保存了线程运行时所需要用到的变量,这个变量就相当于主内存这个变量的副本一样,线程运行使用的是线程栈中的副本而不是主内存中的变量,在单线程中副本和主内存中的变量是一致的,但是在并发编程中就不一定了。

 

       举个例子,有一个线程B要执行i=i+2的操作,线程A要执行i=i+1的操作,最后的结果应该是i=3,但是实际情况是i可能=1,因为线程B中i+2后i=2的值还没有写入到主内存,线程A也不知道i的值发生了变化,当线程A执行完i=0+1,最后i的值为1,然后写入到主内存,i的值为1,就像下图所示。

volatile关键字的用法

为了避免这个问题我们可以使用volatile关键字,使用volatile定义的变量i就不会出现这种情况,因为如果线程B修改了变量i的话,线程A就知道变量i的值发生了改变,就会使用修改过的值。如下图:

volatile关键字的用法

这就是volatile关键字可以使变量保证在内存中的可见性。

二、禁止指令重排序

       什么是指令重排序,为什么要指令重排序,为了减少内存操作速度慢于cpu执行速度带来的cpu空置的影响,java虚拟机会按照自己制定的一些规则,打乱代码原来的顺序,然后按照打乱后的顺序执行,这就是指令重排序,显然指令重排序在并发编程时也会出现对同一个变量的取值问题,在这种情况下可以使用volatile关键字进行修饰变量,为什么不使用synchronized关键字呢,简单的说因为synchronized花销较大,而volatile花销较少。