java编程细节总结(八):详解volatile关键字

导读:

       volatile是一种轻量级锁,它在java中是一个很常用的存在。我们常把volatile更加倾向于变量而不是锁,因为在代码阅读的过程中它是用来修饰变量的,同时,volatile 变量不会像锁那样造成线程阻塞,因此也很少造成可伸缩性问题。


一、volatile关键字

        volatile在java中提供一种较轻量级的锁功能,同时它具有两个特性:

一、volatile修饰的变量保证此变量对所有的线程的可见性;

二、禁止指令重排序

(1)volatile修饰的变量保证此变量对所有的线程的可见性(所有线程共享volatile关键字的变量  )

         这个是什么意思呢?在java虚拟机(jvm)中存在内存模型——JMM(Java Memory Model)。内存模型中有主内存和工作内存的概念,但是规定每个线程都有一个私有的本地内存,存放每个线程的变量。 与本地内存不同的是,主内存存放着所有线程共享的变量。如下图所示

               java编程细节总结(八):详解volatile关键字_第1张图片

       在每个线程修改后的变量值实际上是存放到对应的本地内存下的。所以volatile关键字实际上让变量不经过本地内存的存储了,直接存放在主内存中,实现变量的所有线程可见性。

下面是普通变量和volatile的变量的区别:

       1、对于普通变量:读操作会优先读取工作内存的数据,如果工作内存中不存在,则从主内存中拷贝一份数据到工作内存中;写操作只会修改工作内存的副本数据,这种情况下,其它线程就无法读取变量的最新值。

       2、对于volatile变量,读操作时JMM会把工作内存中对应的值设为无效,线程从主内存中读取数据;写操作时JMM会把工作内存中对应的数据刷新到主内存中,这种情况下,其它线程就可以读取变量的最新值。

(2)禁止指令重排序

         重排序是指编译器和处理器为了优化程序性能而对指令序列进行排序的一种手段。这个是什么意思呢?在java中程序顺序执行和指令的重排序执行实际上得到的最终结果是一致的,而且必须保证是一致的。

       当然,重排序也要遵循一定的规则:一、不会根据数据依赖进行重排序(如candy = 1;poo = candy;不用重排序)二、重排序遵循最终结果和顺序执行一致。

      本人理解:在java中重排序是为了很好的优化程序的性能,可能和我们的想法在程序内部执行指令的顺序是不一样的,但是可以保证的是最终的结果和我们预想是一致的(正确的结果)。


同时这里延伸一下,volatile关键字与 synchronized关键字是有所不同的,volatile开销小,synchronized开销大,在一般的多线程情况下使用volatile是比较节省内存的。volatile具有内存可见性,但是不具备操作原子性;synchronized具备内存可见性和操作原子性。

你可能感兴趣的:(java编程细节总结(八):详解volatile关键字)