我们先来想想,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值:
怎样才能避免呢?加个休眠吧。。。