Java中volatile关键字的作用
来源:互联网 发布:股票买卖点提示软件 编辑:程序博客网 时间:2024/05/05 14:45
volatile是Java中用来做同步的一个关键字,之前对它的作用一直理解得不是很透彻。
于是在网上查阅了一些资料,发现也讲得含混不清。
后来在wikipedia(http://en.wikipedia.org/wiki/Volatile_variable#In_Java)上看到了比较完善的解释。总的来说,volatile关键字是用来防止编译器做特定优化的,但具体作用取决于使用的语言(如C, C++, C#, Java)。
在Java中,volatile的作用有两点:
对volatile变量的修改能够立刻被其他线程知道,也就是说,在读取volatile变量的值时,不是从线程本地的cache读取,而是从主内存读取。这样就能保证多线程对同一个变量的读和写有一个全局的顺序。
可以防止编译器做额外的优化(如调整对变量的读写语句的执行顺序,对while循环的优化等)。
网上的资料经常会给出类似这样一个例子:
public class Thread1 extends Thread{ private static boolean flag = false; public void run(){ while(!flag) { // ... } } public void close(){ flag = true; }}
网上的说法是:线程A在执行run()方法中的while循环,这时线程B调用了close()方法,结果线程A停不下来。因为编译器观察到while循环中没有改变flag的值,就将while(!flag)优化成了while(true)。
开始我对编译器是否会优化到这种程度表示怀疑。因为据我实际测试,无论对flag是否加volatile关键字修饰,都是可以停下来的。据我的推测(根据上述volatile的作用第一点),线程A虽然不能在第一时间知道flag值的改变,但是最终还是会读到正确的值,从而停止while循环。
后来我去掉volatile关键字,再将while循环的执行次数变长(例如达到1000000000次),这时再调用close()方法,线程A不会停下来了。所以可能HotSpot在while循环执行的次数足够多时才会做while(true)的优化。
对于volatile的第二点作用,还有这样一个例子可以用来解释(来自http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#volatile):
public class VolatileExample { int x = 0; volatile boolean v = false; public void writer() { x = 42; v = true; } public void reader() { if (v == true) { //uses x - guaranteed to see 42. } }}
在注释处,我们希望看到的是x的值等于42。但是如果不加volatile修饰变量v,那么编译器有可能会调整writer()函数中两条语句的执行顺序,导致在注释处x的值不确定(也可能是0)。加上volatile后,便可以防止编译器为了优化随意调整语句的执行顺序。
与普通加锁方式的区别是:加锁机制既可以确保可见性又可以确保原子性,而volatile变量只能确保可见性。
- Java:java中关键字volatile的作用
- java中关键字volatile的作用
- java中关键字volatile的作用
- java中关键字volatile的作用 .
- java中关键字volatile的作用
- java中关键字volatile的作用
- java中关键字volatile的作用
- java中关键字volatile的作用
- java中关键字volatile的作用
- java中关键字volatile的作用 . .
- java中关键字volatile的作用
- java中关键字volatile的作用 编辑
- java中关键字volatile的作用
- java中关键字volatile的作用
- java中关键字volatile的作用
- java中关键字volatile的作用
- java中关键字volatile的作用
- java中关键字volatile的作用
- Java深度学习(一)内存模型(堆和栈工作原理,String详解)
- Java 1.7 里有什么?
- 字符编码的简单总结
- Hibernate get和load区别
- Java中容器的迭代器的fail-fast机制
- Java中volatile关键字的作用
- 关于Java字符编码几个容易弄错的问题
- Java 8新特性探究(九)跟OOM:Permgen说再见吧
- Java 8 之 java.time 包
- 6.OkHttp的缓存管理
- maven 教程一 入门
- epoll服务器的介绍和实现
- 小议时序调度Timer和Quartz
- Netty 4.0 源码分析(四):ByteBuf