最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java內(nèi)存模型之happens-before概念詳解

 更新時間:2021年06月13日 11:19:38   作者:Liziba  
happens-before原則非常重要,它是判斷數(shù)據(jù)是否存在競爭、線程是否安全的主要依據(jù),依靠這個原則,我們解決在并發(fā)環(huán)境下兩操作之間是否可能存在沖突的所有問題。下面我們就一個簡單的例子稍微了解下happens-before知識,感興趣的朋友一起看看吧

簡介

happens-before是JMM的核心概念。理解happens-before是了解JMM的關(guān)鍵。

1、設(shè)計意圖

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

  • 程序員角度,希望內(nèi)存模型易于理解、易于編程。希望是一個強內(nèi)存模型。
  • 編譯器和處理器角度,希望減少對它們的束縛,以至于編譯器和處理器可以做更多的性能優(yōu)化。希望是一個弱內(nèi)存模型。

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

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

​下面通過一段代碼來看JSR-133如何實現(xiàn)這兩個目標:

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

上述代碼存在如下happens-before關(guān)系:

  1. A happens-before B
  2. B happens-before C
  3. A happens-before C

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

  • 會改變程序執(zhí)行結(jié)果的重排序
  • 不會改變程序執(zhí)行結(jié)果的重排序

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

  • 對于會改變程序執(zhí)行結(jié)果的重排序,JMM要求編譯器和處理器必須禁止
  • 對于不會改變程序執(zhí)行結(jié)果的重排序,JMM不做要求(JMM運行)

JMM設(shè)計示意圖:

在這里插入圖片描述

JMM設(shè)計示意圖

總結(jié):

  • JMM給程序員提供的happens-before規(guī)則能滿足程序員的需求。簡單易懂,具有足夠強的內(nèi)存可見性保證。
  • JMM對編譯器和處理器的束縛盡可能少。遵循的原則是:不改變程序的執(zhí)行結(jié)果(正確同步或單線程執(zhí)行),編譯器和處理器可以任意優(yōu)化。

 2、happens-before的定義

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

Java中的應(yīng)用:
JSR-133使用happens-before來指定兩個操作之間的執(zhí)行順序。JMM可以通過happens-before關(guān)系向程序員提供跨線程的內(nèi)存可見性保證。

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

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

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

  • as-if-serial語義保證單線程內(nèi)程序的執(zhí)行結(jié)果不被改變,happens-before關(guān)系保證正確同步的多線程程序的執(zhí)行結(jié)果不改變
  • as-if-serial語義給編程者一種單線程是按程序順序執(zhí)行的幻境;happens-before關(guān)系給編程者一種正確同步的多線程是按照happens-before指定的順序執(zhí)行的幻境。

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

3、happens-before規(guī)則

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

  • 程序順序規(guī)則
  • 監(jiān)視器鎖規(guī)則
  • volatile變量規(guī)則
  • 傳遞性
  • start()規(guī)則
  • join()規(guī)則

3.1 volatile寫-讀

volatile寫-讀建立的happens-before關(guān)系

在這里插入圖片描述

happens-before關(guān)系示意圖

分析上圖:

  1. 1 happens-before 2和3 happens-before 4由程序順序規(guī)則產(chǎn)生。由于編譯器和處理器遵循as-if-serial語義,也就是說,as-if-serial語義保證了程序順序規(guī)則。因此可以把程序順序規(guī)則看成是對as-if-serial語義的“封裝”。
  2. 2 happens-before 3 是有volatile規(guī)則產(chǎn)生。一個volatile變量的讀,總是能看到(任意線程)對這個volatile變量的最后寫入。
  3. 1 happens-before 4 是由傳遞性規(guī)則產(chǎn)生的。這里的傳遞性是由volatile的內(nèi)存屏障插入策略和volatile的編譯器重排序規(guī)則來共同保證的。

3.2 start()規(guī)則

假設(shè)線程A在執(zhí)行的過程中,通過執(zhí)行ThreadB.start()來啟動線程B;同時,假設(shè)線程A在執(zhí)行ThreadB.start()之前修改了一個共享變量,線程B在執(zhí)行后會讀取這些共享變量。
start()程序?qū)?yīng)的happens-before關(guān)系圖:

在這里插入圖片描述

分析上圖:

  • 1 happens-before
  • 2 由程序順序規(guī)則產(chǎn)生2 happens-before 4 由start規(guī)則產(chǎn)生
  • 1 happens-before 4 由傳遞性規(guī)則產(chǎn)生

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

3.3 join()規(guī)則

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

在這里插入圖片描述

分析上圖:

  1. 2 happens-before
  2. 4 由join()規(guī)則產(chǎn)生4 happens-before 5 由程序順序規(guī)則產(chǎn)生
  3. 2 happens-before 5 由傳遞性規(guī)則產(chǎn)生

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

文章總結(jié)至《Java并發(fā)編程藝術(shù)》,下篇總結(jié)“雙重檢查所定與延遲初始化”,敬請關(guān)注。

以上就是Java內(nèi)存模型之happens-before概念詳解的詳細內(nèi)容,更多關(guān)于Java內(nèi)存模型 happens-before的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • java使用Jco連接SAP過程

    java使用Jco連接SAP過程

    這篇文章主要介紹了java使用Jco連接SAP過程,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • SprinBoot如何集成參數(shù)校驗Validator及參數(shù)校驗的高階技巧

    SprinBoot如何集成參數(shù)校驗Validator及參數(shù)校驗的高階技巧

    這篇文章主要介紹了SprinBoot如何集成參數(shù)校驗Validator及參數(shù)校驗的高階技巧包括自定義校驗、分組校驗,本文分步驟給大家介紹的非常詳細,需要的朋友可以參考下
    2022-05-05
  • IDEA導(dǎo)入geoserver項目的詳細步驟及注意事項

    IDEA導(dǎo)入geoserver項目的詳細步驟及注意事項

    由于GeoServer是基于Java開發(fā)的。因此在安裝之前,必須確保安裝了Java。本文給大家分享IDEA導(dǎo)入geoserver項目的詳細步驟及注意事項,感興趣的朋友一起看看吧
    2021-06-06
  • Spring學(xué)習(xí)筆記之RestTemplate使用小結(jié)

    Spring學(xué)習(xí)筆記之RestTemplate使用小結(jié)

    這篇文章主要給大家介紹了關(guān)于Spring學(xué)習(xí)筆記之RestTemplate使用的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-08-08
  • springboot中如何使用minio存儲容器

    springboot中如何使用minio存儲容器

    大家好,本篇文章主要講的是springboot中如何使用minio存儲容器,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-02-02
  • idea創(chuàng)建的idea項目時springframework出現(xiàn)紅色的原因和解決方法

    idea創(chuàng)建的idea項目時springframework出現(xiàn)紅色的原因和解決方法

    當使用 IntelliJ IDEA 創(chuàng)建 Spring Framework 項目時,springframework 出現(xiàn)紅色可能是因為相關(guān)的 Spring Framework 依賴沒有正確加載或項目的配置有問題,本文給大家介紹了一些常見的原因和解決方法,需要的朋友可以參考下
    2023-09-09
  • Flink結(jié)合Kafka實現(xiàn)通用流式數(shù)據(jù)處理

    Flink結(jié)合Kafka實現(xiàn)通用流式數(shù)據(jù)處理

    這篇文章將和大家一起深入探討Flink和Kafka的關(guān)系以及它們在數(shù)據(jù)流處理中的應(yīng)用,并提供一些最佳實踐和實際案例,希望對大家有一定的幫助
    2025-03-03
  • Java 遞歸查詢部門樹形結(jié)構(gòu)數(shù)據(jù)的實踐

    Java 遞歸查詢部門樹形結(jié)構(gòu)數(shù)據(jù)的實踐

    本文主要介紹了Java 遞歸查詢部門樹形結(jié)構(gòu)數(shù)據(jù)的實踐,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • Java中的@Cacheable注解的作用詳解

    Java中的@Cacheable注解的作用詳解

    這篇文章主要介紹了Java中的@Cacheable注解的作用詳解, 使用 @Cacheable 注解就可以將運行結(jié)果緩存,以后查詢相同的數(shù)據(jù),直接從緩存中取,不需要調(diào)用方法,需要的朋友可以參考下
    2023-10-10
  • spring緩存cache的使用詳解

    spring緩存cache的使用詳解

    這篇文章主要介紹了spring緩存cache的使用詳解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10

最新評論

台前县| 弥渡县| 普格县| 淮滨县| 长垣县| 乌拉特后旗| 郎溪县| 鹤岗市| 昭通市| 东方市| 昂仁县| 连州市| 通海县| 疏附县| 邢台市| 扎鲁特旗| 黔江区| 德昌县| 昆山市| 开平市| 无锡市| 义乌市| 清苑县| 金秀| 商都县| 保定市| 新宁县| 深水埗区| 仪征市| 福清市| 大邑县| 微山县| 兴城市| 乌苏市| 玉山县| 湘潭县| 民和| 化德县| 合肥市| 获嘉县| 平乐县|