我們先來想想,synchronized的功能:
1.同步,搞互斥鎖,使線程不能交叉執行;
2.維護共享變量在多個線程之間的可見性;
public class demo {
private boolean ready=false;
private int result=0;
private int number=1;
public synchronized void write(){
ready=true;
number=2;
}
public synchronized void read(){
if(ready){
result=number*3;
}
System.out.println("result的值爲:"+result);
}
public class ReadWriteThread extends Thread{
private boolean flag;
public ReadWriteThread(boolean flag){
this.flag=flag;
}
public void run(){
if(flag)
write();
else{
read();
}
}
}
public static void main(String[] args) throws InterruptedException{
demo synDemo=new demo();
synDemo.new ReadWriteThread(true).start(); //1
//Thread.sleep(1000);
synDemo.new ReadWriteThread(false).start(); //2
}
}
大家先別往下看,先猜猜這段程序的輸出結果是什麼。^-^先別往下看哦親。
大家可能覺得結果不就是result=6嗎?
哈哈,那你就中招了。
我們很容易忽略JMM裏的一條規則:
指令重排序。
在這段程序裏,編譯器可能不會進行重排序,但是也可能進行重排序,主程序中1、2兩句進行重排序的話,結果就是0了。
然而,如果你把代碼敲出來你就會發現出現0的機率還是很低的。這是因爲編譯器會揣摩我們的意圖,讓6儘可能的出現。
下面看寶寶執行了多次程序之後得到的一個0值:
怎樣才能避免呢?加個休眠吧。。。