首先,什么是重排序计算机在执行过程中,为了提高性能,会对编译器和编译器做指令重排。
这么做为啥可以提高性能呢
我们知道计算机在执行的时候都是一个个指令去执行,不同的指令可能操作的硬件不一样,在执行的过程中可能会产生中断,打个比方,两个指令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。
本文标题:面试官:有了解过指令重排吗,什么是Happens-Before
标题URL:http://www.shufengxianlan.com/qtweb/news20/478420.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联