你以为在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值:

怎样才能避免呢?加个休眠吧。。。

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