日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
面試官:有了解過指令重排嗎,什么是Happens-Before

重排序

首先,什么是重排序計(jì)算機(jī)在執(zhí)行過程中,為了提高性能,會(huì)對編譯器和編譯器做指令重排。

這么做為啥可以提高性能呢

我們知道計(jì)算機(jī)在執(zhí)行的時(shí)候都是一個(gè)個(gè)指令去執(zhí)行,不同的指令可能操作的硬件不一樣,在執(zhí)行的過程中可能會(huì)產(chǎn)生中斷,打個(gè)比方,兩個(gè)指令a和b他們操作的東西各不相同,如果加載a的時(shí)候停頓了,b就加載不到,但是實(shí)際上它們互補(bǔ)影響,我也可以先加載b在加載a,所以指令重排是減少停頓的一種方法,這樣大大提高了效率。

指令重排的方式

指令重排一般分為以下三種:

  • 編譯器優(yōu)化重新安排語句的執(zhí)行順序。
  • 指令并行重排利用指令級并行技術(shù)將多個(gè)指令并行執(zhí)行,如果指令之前沒有數(shù)據(jù)依賴,處理器可以改變對應(yīng)機(jī)器指令的執(zhí)行順序。
  • 內(nèi)存系統(tǒng)重排由于處理使用緩存和讀寫緩沖區(qū),所以它們是亂序的。

指令重排可以保證串行語義一致,但是沒有義務(wù)保證多線程間的語義也一致**。所以在多線程下,指令重排序可能會(huì)導(dǎo)致一些問題。

順序一致性模型

順序一致性模型是一個(gè)「理論參考模型」,內(nèi)存模型在設(shè)計(jì)的時(shí)候都會(huì)以順序一致性內(nèi)存模型作為參考。

數(shù)據(jù)競爭

我們知道在多線程情況下,同時(shí)讀寫一個(gè)變量會(huì)導(dǎo)致結(jié)果的不確定性,這就存在了數(shù)據(jù)競爭,相反的如果線程在同步情況下,就不存在數(shù)據(jù)競爭。

JMM對于同步的多線程情況下,程序執(zhí)行可以保證順序一致性,同步包括了使用volatile、final、synchronized等關(guān)鍵字來實(shí)現(xiàn)「多線程下的同步」,這里的前提正確使用它們,如果使用不當(dāng),就不能保證

什么是順序一致性模型

我們在上節(jié)給大家講了Java的內(nèi)存模型,提到了內(nèi)存可見性的概念,順序一致性模型它的最終目的就是保證內(nèi)存的可見性。

它主要有兩大特性:

  • 一個(gè)線程中的所有操作必須按照程序的順序(代碼順序)來執(zhí)行。
  • 不管線程是否同步,所有線程保持單一的執(zhí)行順序并且可見,且是原子性

JMM中同步的順序一致性

在JMM中,臨界區(qū)(同步方法或同步塊)的代碼可以發(fā)生重排,但對其它線程是無感知的,這樣既提高了執(zhí)行效率又不影響最終結(jié)果

JMM中未同步的順序一致性

  • JMM沒有保證未同步程序的執(zhí)行結(jié)果與該程序在順序一致性中執(zhí)行結(jié)果一致。
  • JMM不保證單線程內(nèi)的操作會(huì)按程序的順序執(zhí)行(因?yàn)橹噶钪嘏?。
  • JMM不保證所有線程能看到一致的操作執(zhí)行順序(因?yàn)椴荒鼙WC所以操作立即可見)。
  • JMM不保證對64位的long型和double型變量的寫操作具有原子性。

什么是happens-before

JMM提供了「happens-before規(guī)則」(JSR-133規(guī)范), 開發(fā)者可以遵循這種規(guī)范編寫程序,可以保證程序在JMM中具有強(qiáng)的內(nèi)存可見性。JMM使用happens-before的概念來定制兩個(gè)操作之間的執(zhí)行順序。這兩個(gè)操作可以在一個(gè)線程以內(nèi),也可以是不同的線程之間。因此,JMM可以通過happens-before關(guān)系向程序員提供跨線程的內(nèi)存可見性保證。

happens-before關(guān)系的定義如下:

  1. 如果一個(gè)操作happens-before另一個(gè)操作,那么第一個(gè)操作的執(zhí)行結(jié)果將對第二個(gè)操作可見,而且第一個(gè)操作的執(zhí)行順序排在第二個(gè)操作之前。
  2. 「兩個(gè)操作之間存在happens-before關(guān)系,并不意味著Java平臺的具體實(shí)現(xiàn)必須要按照happens-before關(guān)系指定的順序來執(zhí)行。如果重排序之后的執(zhí)行結(jié)果,與按happens-before關(guān)系來執(zhí)行的結(jié)果一致,那么JMM也允許這樣的重排序。」

總之,「如果操作A happens-before操作B,那么操作A在內(nèi)存上所做的操作對操作B都是可見的,不管它們在不在一個(gè)線程。」

在Java中,有以下天然的happens-before關(guān)系:

  • 程序順序規(guī)則:一個(gè)線程中的每一個(gè)操作,happens-before于該線程中的任意后續(xù)操作。
  • 監(jiān)視器鎖規(guī)則:對一個(gè)鎖的解鎖,happens-before于隨后對這個(gè)鎖的加鎖。
  • volatile變量規(guī)則:對一個(gè)volatile域的寫,happens-before于任意后續(xù)對這個(gè)volatile域的讀。
  • 傳遞性:如果A happens-before B,且B happens-before C,那么A happens-before C。
  • start規(guī)則:ThreadA start happens-before ThreadB start
  • join規(guī)則:如果線程A執(zhí)行操作ThreadB.join()并成功返回,那么線程B中的任意操作happens-before于線程A從ThreadB.join()操作成功返回。

結(jié)束語

本節(jié)內(nèi)容可能不像之前那么好理解,比較抽象,所以本文也有不足的地方,大家自己可以多查查一些資料,綜合理解。下一節(jié),帶大家深入學(xué)習(xí)一下Java的volatile。


本文標(biāo)題:面試官:有了解過指令重排嗎,什么是Happens-Before
URL地址:http://www.5511xx.com/article/cojojsd.html