你以爲在java裏用synchronized就能萬事大吉了嗎?

我們先來想想,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值:

怎樣才能避免呢?加個休眠吧。。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章