Happenbefore:指令重排,就是代码与代码之间没有相互的联系,没有相互的依赖,就是我的把后面的结果往前提不会影响整个的结果,这就叫做指令重排。
由上图来理解机器是怎么来编译和运行代码的。先将代码翻译成指令。
第二步,从对应的寄存器中拿出对应的值,也就是工作空间拷贝主存的数据,
第三步,这两个值计算得到结果124
第四步,将结果同步到主存里面
一条指令执行的步骤:1、获取指令;2、将指令解码翻译,在寄存器中取值;3、操作;4、然后把结果写回;
指令重排就是比如 a=a+b; b=a;flag=true;这三句代码翻译成指令,然后先执行a=a+b;假设这行代码执行很慢,cpu就不愿意等了,就看下一句代码,然后下一句代码和第一句代码有关系,然后第三句代码和前两句没有联系,cpu优化程序性能,然后就把第三句代码提前了。
数据依赖:
没有依赖就可以可能发生重排。
案例:影响结果的重排
package com.cb.thread.day06;
public class HappenBefore {
//变量1
static int a = 0;
//变量2
static boolean flag = false;
public static void main(String[] args) throws InterruptedException {
//线程1 更改数据
class Thread1 extends Thread{
public void run() {
a=1;
flag = true;
}
}
//线程2 读取数据
class Thread2 extends Thread{
public void run() {
if(flag){
a*=1;
}
if(a==0){
System.out.println("happen before a--> "+a);
}
}
}
for (int i = 0; i < 10; i++) {
a=0;
flag=true;
HappenBefore hb = new HappenBefore();
Thread1 t1 = new Thread1();
Thread2 t2 = new Thread2();
new Thread2().start();
t1.start();
t2.start();
//合并线程
t1.join();
t2.join();
}
}
}
运行结果:
if(a==0){
System.out.println("happen before a–> "+a);
}
如果a等于0进去了,然后打印a,然后却打a=1;,发生了指令重排;