一句话解释什么是Happens-Before

153 阅读2分钟

什么是Happens-Before?

一句话解释:前面的操作结果可以被后面的操作感知。

举个一句话概括的代码例子:

    public void happensBefore() {
        int a = 1;//操作1
        int b = a + 3;//操作2
    }
   

操作1对a变量赋值为1,操作2对b变量赋值为a+3;Happens-Before做的就是让操作2可以直接感知到操作1对a的赋值。

注意项:Happens-Before不是操作1在操作2之前执行,一定不要这样理解!!!

为什么要这样做?

指令重排序

Java中编译器加载和CPU执行在优化程序执行时,可能会对程序的执行指令做出一些顺序的调整,这就是指令重排序。

编译器重排序:

在编译器重排序中编译器load指令时往往会对关联的指令进行重排序,比如以下的例子,

    public void happensBefore() {
        int a = 1;//操作1:编译器对a进行load和store
        int b = 3;//操作2;编译器对b进行load和store
        a = a + 3;//操作3:编译器对a进行load和store
    }

编译器中正常会load三次操作,但是重排序后会把操作3提前到操作2之前和操作1一起执行,操作2后执行调整了操作2和操作3的顺序。这样就减少了程序指令。

CPU重排序

而在指令交给CPU执行过程中也会存在重排序的情况,CPU允许将多条指令不按照程序规定的顺序分开执行发送给各单元处理。这种重排序不是随意的排序而是CPU能够保证程序最终得到正确的结果。

以上所有的指令重排序都是为了增加程序的执行效率,保证程序更快的执行。(在Java中volatile关键字避免了这种重排序)

引用

  • 深入理解Java虚拟机第二版