91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java內存模型之happens-before的示例分析

發布時間:2021-06-15 09:53:45 來源:億速云 閱讀:191 作者:小新 欄目:開發技術

這篇文章將為大家詳細講解有關Java內存模型之happens-before的示例分析,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

簡介

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

1、設計意圖

JMM的設計需要考慮兩個方面,分別是程序員角度和編譯器、處理器角度:

  • 程序員角度,希望內存模型易于理解、易于編程。希望是一個強內存模型。

  • 編譯器和處理器角度,希望減少對它們的束縛,以至于編譯器和處理器可以做更多的性能優化。希望是一個弱內存模型。

因此JSR-133專家組設計JMM的核心目標就兩個:

為程序員提供足夠強的內存模型對編譯器和處理器的限制盡可能少

下面通過一段代碼來看JSR-133如何實現這兩個目標:

double pi = 3.14;			//A
double r  = 1.0;			//B
double area = pi * r * r 	//C

上述代碼存在如下happens-before關系:

  1. A happens-before B

  2. B happens-before C

  3. A happens-before C

這3個happens-before關系中,第二個和第三個是必須的,而第一個是非必須的(A、B操作之間重排序,程序執行結果不會發生改變)。
JMM把happens-before要求禁止的重排序分為下面的兩類:

  • 會改變程序執行結果的重排序

  • 不會改變程序執行結果的重排序

JMM對這兩種不同性質的重排序,采取了不同的策略:

  • 對于會改變程序執行結果的重排序,JMM要求編譯器和處理器必須禁止

  • 對于不會改變程序執行結果的重排序,JMM不做要求(JMM運行)

JMM設計示意圖:

Java內存模型之happens-before的示例分析

JMM設計示意圖

總結:

  • JMM給程序員提供的happens-before規則能滿足程序員的需求。簡單易懂,具有足夠強的內存可見性保證。

  • JMM對編譯器和處理器的束縛盡可能少。遵循的原則是:不改變程序的執行結果(正確同步或單線程執行),編譯器和處理器可以任意優化。

 2、happens-before的定義

起源:
happens-before規則來源于Leslie Lamport《Time, Clocks and the Ordering of Events in a Distributed System》。該論文中使用happens-before來定義分布式系統中事件之間的偏序關系(partial ordering),該文中給出了一個分布式算法,能用來將偏序關系擴展為某種全序關系。

Java中的應用:
JSR-133使用happens-before來指定兩個操作之間的執行順序。JMM可以通過happens-before關系向程序員提供跨線程的內存可見性保證。

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

如果操作A happens-before 操作B,那么A操作的執行結果將會對操作B可見,且操作A的執行順序排在操作B之前——JMM對程序員的承諾兩個操作存在happens-before關系,并不意味著Java平臺的具體實現必須按照happens-before的順序來執行。如果重排序不改變程序執行結果(與happens-before)規則一致,那么這種重排序是不非法的(JMM允許這種重排序)。——JMM對編譯器和處理器的束縛原則

happens-before和as-if-serial語義:
從上述來看,happens-before和as-if-serial語義本質上是一回事

  • as-if-serial語義保證單線程內程序的執行結果不被改變,happens-before關系保證正確同步的多線程程序的執行結果不改變

  • as-if-serial語義給編程者一種單線程是按程序順序執行的幻境;happens-before關系給編程者一種正確同步的多線程是按照happens-before指定的順序執行的幻境。

兩者的目的都是為了在不改變程序執行結果的前提下,盡可能的提高程序的執行效率。

3、happens-before規則

《JSR-133:Java Memory Model and Thread Specification》定義了如下happens-before規則

  • 程序順序規則

  • 監視器鎖規則

  • volatile變量規則

  • 傳遞性

  • start()規則

  • join()規則

3.1 volatile寫-讀

volatile寫-讀建立的happens-before關系

Java內存模型之happens-before的示例分析

happens-before關系示意圖

分析上圖:

  1. 1 happens-before 2和3 happens-before 4由程序順序規則產生。由于編譯器和處理器遵循as-if-serial語義,也就是說,as-if-serial語義保證了程序順序規則。因此可以把程序順序規則看成是對as-if-serial語義的“封裝”。

  2. 2 happens-before 3 是有volatile規則產生。一個volatile變量的讀,總是能看到(任意線程)對這個volatile變量的最后寫入。

  3. 1 happens-before 4 是由傳遞性規則產生的。這里的傳遞性是由volatile的內存屏障插入策略和volatile的編譯器重排序規則來共同保證的。

3.2 start()規則

假設線程A在執行的過程中,通過執行ThreadB.start()來啟動線程B;同時,假設線程A在執行ThreadB.start()之前修改了一個共享變量,線程B在執行后會讀取這些共享變量。
start()程序對應的happens-before關系圖:

Java內存模型之happens-before的示例分析

分析上圖:

  • 1 happens-before

  • 2 由程序順序規則產生2 happens-before 4 由start規則產生

  • 1 happens-before 4 由傳遞性規則產生

因此線程A執行ThreadB.start()之前對共享變量所做的修改,在線程B執行后都將確保對線程B可見。

3.3 join()規則

假設線程A執行的過程中,通過執行ThreadB.join()來等待線程B終止;則線程B在終止之前修改了一些共享變量,線程A從ThreadB.join()返回后會讀這些共享變量。
join()程序的happens-before關系圖:

Java內存模型之happens-before的示例分析

分析上圖:

  1. 2 happens-before

  2. 4 由join()規則產生4 happens-before 5 由程序順序規則產生

  3. 2 happens-before 5 由傳遞性規則產生

因此線程A執行操作ThreadB.join()并成功返回,線程B中任意操作都將對線程A可見。

關于“Java內存模型之happens-before的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

桂东县| 扎囊县| 上栗县| 清苑县| 无极县| 齐河县| 英超| 南川市| 古交市| 乌鲁木齐县| 彩票| 庄河市| 桓台县| 渝中区| 东乌珠穆沁旗| 南乐县| 洞口县| 淮滨县| 咸宁市| 郸城县| 休宁县| 出国| 台湾省| 独山县| 玉山县| 华容县| 鲜城| 汝城县| 图片| 炉霍县| 阜阳市| 富平县| 四子王旗| 稻城县| 达拉特旗| 万山特区| 霸州市| 郑州市| 西昌市| 福海县| 扶沟县|