一、
指令重排序: 编译器或运行时环境 为了优化程序性能而采取的对指令进行重新排序执行的一种手段。
指令重排序发生在不影响语义的情况下,也就是在 单线程下,重排序不能导致运行结果发生变化。(即遵循as-if-serial语义)
进一步解释就是在不影响执行结果的情况下,代码在jvm内的执行顺序并不是严格按照书写顺序的,出于性能方面的考虑,jvm会对它进行重排序。
如果两个操作访问同一个变量,且这两个变量有一个为写操作,则这两个操作之间是有数据依赖性的,也就是不能进行重排序。
二、
例一:
int a = 1;
int b = 2;
这两句是有可能发生指令重排序的,因为他们互不影响
例二:
int a ;
a = 1;
a = a+2;
这三句之间任意两句都不会发生重排序,因为他们之间是具有数据依赖性的。
三、对于并发程序
public void write(){
a = 1;
flag = true;
}
public void read(){
if(flag){
System.out.println("a==1");
System.out.println(a);
}
else{
System.out.println("a!=0");
System.out.println(a);
}
}
由于指令重排序的存在,当线程一执行wirte,线程执行read时,会存在flag已经被置为true,而a还没有被赋值的情况,此时在read里判断,进入分支,出现意料之外的情况。