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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值