十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决

首先,什么是重排序计算机在执行过程中,为了提高性能,会对编译器和编译器做指令重排。
这么做为啥可以提高性能呢
我们知道计算机在执行的时候都是一个个指令去执行,不同的指令可能操作的硬件不一样,在执行的过程中可能会产生中断,打个比方,两个指令a和b他们操作的东西各不相同,如果加载a的时候停顿了,b就加载不到,但是实际上它们互补影响,我也可以先加载b在加载a,所以指令重排是减少停顿的一种方法,这样大大提高了效率。
指令重排一般分为以下三种:
指令重排可以保证串行语义一致,但是没有义务保证多线程间的语义也一致**。所以在多线程下,指令重排序可能会导致一些问题。
顺序一致性模型是一个「理论参考模型」,内存模型在设计的时候都会以顺序一致性内存模型作为参考。
我们知道在多线程情况下,同时读写一个变量会导致结果的不确定性,这就存在了数据竞争,相反的如果线程在同步情况下,就不存在数据竞争。
JMM对于同步的多线程情况下,程序执行可以保证顺序一致性,同步包括了使用volatile、final、synchronized等关键字来实现「多线程下的同步」,这里的前提正确使用它们,如果使用不当,就不能保证
我们在上节给大家讲了Java的内存模型,提到了内存可见性的概念,顺序一致性模型它的最终目的就是保证内存的可见性。
它主要有两大特性:
在JMM中,临界区(同步方法或同步块)的代码可以发生重排,但对其它线程是无感知的,这样既提高了执行效率又不影响最终结果
JMM提供了「happens-before规则」(JSR-133规范), 开发者可以遵循这种规范编写程序,可以保证程序在JMM中具有强的内存可见性。JMM使用happens-before的概念来定制两个操作之间的执行顺序。这两个操作可以在一个线程以内,也可以是不同的线程之间。因此,JMM可以通过happens-before关系向程序员提供跨线程的内存可见性保证。
happens-before关系的定义如下:
总之,「如果操作A happens-before操作B,那么操作A在内存上所做的操作对操作B都是可见的,不管它们在不在一个线程。」
在Java中,有以下天然的happens-before关系:
本节内容可能不像之前那么好理解,比较抽象,所以本文也有不足的地方,大家自己可以多查查一些资料,综合理解。下一节,带大家深入学习一下Java的volatile。