指令重排序对多线程的影响

指令重排序

对单线程程序执行结果没有影响、虚拟机为优化和提升性能而对指令进行的一种重排序。例如:

int a,b,c=0;
a = 1;
b = 1;
c = a+b;

&

int a,b,c=0;
b = 1;
a = 1;
c = a+b;

结果是一样的。

但如果是在多线程中,em…,假设有一个加法:
假设有boolean flag = false;int a,b=0;

public  int plus(){
	if(flag == false){
	a = 1;
	b = 1;
 	flag = true;//说明a,b已经赋值
	}
	return a+b;
}

现在假定有A、B两个线程同时调用plus()方法。

注意:

在if块儿中,三个赋值操作可以交换,因为不影响最终的结果(对单线程来说),假设过程如下:

线程A线程B
flag==false
a=1
flag = truea+b
b=1
a+b
结果为2结果为1

这显然违背了指令重排序的初衷,说明其在多线程中不适用。大家以后写多线程一定要注意这个问题。

单例模式中的DCL(double checked locking)

public class DCL{
 private static DCL s;
 private DCL(){
  
 }
 public static  DCL getInstance() {
  if(s==null) {
   DCL sl;
   synchronized(DCL.class) {
    sl = s;
    if(sl == null) {
     synchronized(DCL.class) {
      if(sl == null) 
      sl = new DCL();
     }
     s = sl;
    }
   }
  }
  return s;
 }
}

这是修订过够的DCL,getInstance()方法中尝试引入第二个DCL变量以及第二次加锁解决指令重排序带来的问题。但注意在第二个if块儿中,同步语句块和赋值语句s = sl仍然存在指令重排序问题(这里可能是,同步块儿可以确保创建新DCL变量连续地完成,但s=sl这个赋值动作和同步块儿是平行的)。

也可以在方法名前使用volatile关键字禁止重排序。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值