JMM與happens-before

來源:互聯網
上載者:User

標籤:volatil   程式   演算法   監視器   好的   spec   限制   執行   記憶體模型   

happens-before是JMM最核心的概念,理解happens-before是理解JMM的關鍵。

一.JMM的設計

  首先,讓我們先分析一下JMM的設計意圖。從JMM的設計者的角度,在設計JMM的時候要考慮一下兩個關鍵因素:
  1.程式員對記憶體模型的使用。程式員希望記憶體模型易於理解、易於編程。程式員希望基於一個強記憶體模型來編寫代碼。

  2.編譯器和處理器對記憶體模型的實現。編譯器和處理器希望記憶體模型對它們的束縛越少越好,這樣它們就可以做儘可能多的最佳化來提高效能。編譯器和處理器希望實現一個弱記憶體模型。

  上述兩個因素相互矛盾,所以JSR-133專家組在設計JMM時的核心目標就是找到一個好的平衡點:一方面,要為程式員提供足夠強的記憶體可見度保證;另一方面,對編譯器和處理器的限制要儘可能地放鬆。下面讓我們來看JSR-133是如何?這一目標的。

double pi = 3.14;   // Adouble r = 1.0;     // Bdouble area = pi * r * r;  // C

  上述計算圓的面積的代碼中,存在三個happens-before關係:
    A happens-before B

    B happens-before C

    A happens-before C

  在者三個happens-before關係中2和3是必須的,1是不必要的。因此JMM把happens-before要求禁止的重排序分了下面兩類

  1.會改變程式執行結果的重排序

  2.不會改變程式執行結果的重排序

  JMM對這兩種不同性質的重排序,採用了不同的策略,如下:
  1.對於會改變程式執行結果的重排序,JMM要求編譯器和處理器必須禁止這種重排序

  2.對於不會改變程式執行結果的重排序,JMM對編譯器和處理器不做要求(JMM允許這種重排序)

  是JMM的設計

  

  JMM向程式員提供的happens-before規則能滿足程式員的要求,JMM的happens-before規則不但簡單易懂,而且也向程式員提供了足夠強的記憶體可見度保證。

  JMM對編譯器和處理器的束縛已經儘可能少。從上面的分析可以看出,JMM其實是在遵循一個基本原則:只要不改變程式的執行結果(指的是單線程程式和正確同步的多線程程式),編譯器和處理器怎麼最佳化都行。例如,如果編譯器經過細緻的分析後,認定一個鎖只會被單個線程訪問,那麼這個鎖可以被消除。再如,如果編譯器經過細緻的分析後,認定一個volatile變數只會被單個線程訪問,那麼編譯器可以把這個volatile變數當作一個普通變數來對待。這些最佳化既不會改變程式的執行結果,又能提高程式的執行效率。

二.happens-before的定義

  happens-before的概念最初由Leslie Lamport在其一篇影響深遠的論文(《Time,Clocks andthe Ordering of Events in a Distributed System》)中提出。Leslie Lamport使用happens-before來定義分布式系統中事件之間的偏序關係(partial ordering)。Leslie Lamport在這篇論文中給出了一個分布式演算法,該演算法可以將該偏序關係擴充為某種全序關係。

  JSR-133使用happens-before的概念來指定兩個操作之間的執行順序。由於這兩個操作可以在一個線程之內,也可以是在不同線程之間。因此,JMM可以通過happens-before關係向程式員提供跨線程的記憶體可見度保證(如果A線程的寫操作a與B線程的讀操作b之間存在happensbefore關係,儘管a操作和b操作在不同的線程中執行,但JMM向程式員保證a操作將對b操作可見)。

  《JSR-133:Java Memory Model and Thread Specification》對happens-before關係的定義如下:

  1.如果一個操作happens-before另一個操作,那麼第一個操作的執行結果將對第二個操作可見,而且第一個操作的執行順序排在第二個操作之前。

  2.兩個操作之間存在happens-before關係,並不意味著Java平台的具體實現必須要按照happens-before關係指定的順序來執行。如果重排序之後的執行結果,與按happens-before關係來執行的結果一致,那麼這種重排序並不非法。

  上面1是JMM對程式員的承諾。從程式員的角度來說,可以這樣理解happens-before關係:如果A happens-before B,那麼Java記憶體模型將向程式員保證——A操作的結果將對B可見,且A的執行順序排在B之前。注意,這隻是Java記憶體模型向程式員做出的保證!

  上面2是JMM對編譯器和處理器沖排序的約束。MM其實是在遵循一個基本原則:只要不改變程式的執行結果,編譯器和處理器怎麼最佳化都行。happens-before這麼做的目的,都是為了在不改變程式執行結果的前提下,儘可能地提高程式執行的並行度。

三.happens-before規則

  1.程式順序規則:一個線程中的每個操作,happens-before於該線程中的任意後續操作

  2.監視器鎖規則:對一個鎖的解鎖,happens-before於隨後對這個鎖的加鎖

  3.volatile變數規則:對一個volatile域的寫,happens-before於任意後續對這個volatile域的讀

  4.傳遞性:如果A happens-before B,且B happens-before C,那麼A happens-before C

  5.start規則:如果線程A執行操作ThreadB.start()(啟動線程B),那麼A線程的ThreadB.start()操作happens-before於線程B中的任意操作

  6.join規則:如果線程A執行操作ThreadB.join()並成功返回,那麼線程B中的任意操作happens-before於線程A從ThreadB.join()操作成功返回。

JMM與happens-before

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.