詳解
1.對volatile變數的讀寫有一個全域的排序,但是volatile變數跟常規變數的讀寫順序沒並沒有保證
2.volatile的值不會被緩衝,所有線程讀取到的都是當前的(主存中的)值
3.對volatile的變數的讀寫好像是用了synchronized包圍起來一樣
例
| 代碼如下 |
複製代碼 |
package linyumin.test.thread;
/**
*
* @author llade
*
*/
public class VolatileObjectTest {
/**
* 成員變數boolValue使用volatile和不使用volatile會有明顯區別的。
* 本程式需要多試幾次,就能知道兩者之間的區別的。
* @param args
*/
public static void main(String[] args) {
final VolatileObjectTest volObj= new VolatileObjectTest();
Thread t1=new Thread(){
public void run(){
System.out.println("t1 start" );
for (;;){
volObj.waitToExit();
}
}
};
t1.start();
Thread t2=new Thread(){
public void run(){
System.out.println("t2 start" );
for (;;){
volObj.swap();
}
}
};
t2.start();
}
|
boolean boolValue; //加上volatile 修飾的是時候,程式會很快退出,因為volatile 保證各個線程工作記憶體的變數值和主存一致。所以boolValue == !boolValue就成為了可能。
| 代碼如下 |
複製代碼 |
public void waitToExit() {
if (boolValue == !boolValue)System.exit( 0 ); //非原子操作,理論上應該很快會被打斷。實際不是,因為此時的boolValue線上程自己內部的工作記憶體的拷貝,因為它不會強制和主存地區同步,線程2修改了boolValue很少有機會傳遞到線程一的工作記憶體中。所以照成了假的“原子現象”。
}
public void swap() { //不斷反覆修改boolValue,以期打斷線程t1.
boolValue = !boolValue;
}
} |