stand on the shoulders of giants

vilatitle关键字

volatile 易变的

volatile修饰的变量
1. 表示这个变量能被某些编译器未知的因素更改,如硬件中断,其他线程等等。
2. 编译器对访问该变量的代码就不再进行优化,从而能提供对特别地址的稳定访问。

例如:
volatile Int i = 10;
int a = i;  
//...
int b = i;  
---编译器一般优化的做法是什么呢?
如果两次读取i之间的代码没有对i进行过更改操作,那么编译器将上次读取的数据(在Cache里)放在b中,而不是重新从i读取。
如果i是个寄存器变量或表示一个端口数据就容易出错,所以说volatile能确保对特别地址的稳定访问。
volatile修饰后,每次用到i都要重新读取。

---实现线程间数据同步
Java中有"主"内存概念,存放目前变量的“准确值”,每个线程可以有自己的变量拷贝,变量拷贝可以是不同的
而用volatile修饰后的变量不允许有不同于“主”内存区域的变量拷贝。
换句话说,一个变量经volatile修饰后在所有线程中必须是同步的;任何线程中改变了它的值,所有其他线程立即获取到了相同的值。

---避免脏数据
编译器在优化代码时,可能会把经常用到的代码存在Cache里面,然后下一次调用就直接读取Cache而不是内存,这样就大大提高了效率。但是问题也随之而来了。
在多线程程序中,如果把一个变量放入Cache后,又有其他线程改变了变量的值,那么本线程是无法知道这个变化的。它可能会直接读Cache里的数据。但是很不幸,Cache里的数据已经过期了,读出来的是不合时宜的脏数据。这时就会出现bug。

用Volatile声明变量可以解决这个问题。用Volatile声明的变量就相当于告诉编译器,我不要把这个变量写Cache,因为这个变量是可能发生改变的。



 

posted @ 2008-11-09 14:51  DylanWind  阅读(363)  评论(0编辑  收藏  举报