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

關(guān)于Java中的可見性和有序性問題

 更新時間:2023年08月07日 08:54:48   作者:吃飯只吃豬腳飯  
這篇文章主要介紹了關(guān)于Java中的可見性和有序性問題,Java在誕生之初就支持多線程,自然也有針對這三者的技術(shù)方案,今天就學(xué)習(xí)一下Java如何解決其中的可見性和有序性導(dǎo)致的問題,需要的朋友可以參考下

Java 如何解決可見性和有序性問題

并發(fā)場景中,因可見性、原子性、有序性導(dǎo)致問題常常導(dǎo)致bug,Java在誕生之初就支持多線程,自然也有針對這三者的技術(shù)方案

今天就學(xué)習(xí)一下Java如何解決其中的可見性和有序性導(dǎo)致的問題,就引來了今天的主角兒——Java內(nèi)存模型

什么是Java內(nèi)存模型

? 導(dǎo)致可見性的原因是緩存,導(dǎo)致有序性的原因是編譯優(yōu)化

解決可見性、有序性最直接的方法就是禁用緩存和編譯優(yōu)化,但這樣會導(dǎo)致性能下降,我們應(yīng)該想到的是如何按需禁用緩存和編譯優(yōu)化。

? Java內(nèi)存模型規(guī)范了JVM如何提供按需禁用緩存和編譯優(yōu)化的方法,這些方法包括volatilesynchronizedfinal三個關(guān)鍵字以及六項Happens-Before規(guī)則。

使用volatile困惑

volatile關(guān)鍵字在C語言也有,最原始的意義就是禁用CPU緩存。

例如:

volatile int x = 0

表達就是不能使用CPU緩存,必須從內(nèi)存中讀取或者寫入。

看起來沒啥問題,但是在實際使用卻會帶了困惑。

例如:

class VolatileExample {
  int x = 0;
  volatile boolean v = false;
  public void writer() {
    x = 42;
    v = true;
  }
  public void reader() {
    if (v == true) {
      System.out.println(x);
    }
  }
}

假如有A線程調(diào)用writer(),B線程調(diào)用reader(),輸出來的x會是多少呢,在JDK1.5之前,x可能是0或者42,這是因為CPU緩存導(dǎo)致可見性問題,JDK1.5之后Java內(nèi)存模型對volatile語義進行了增強,因此就引出了Happens-Before規(guī)則。

Happens-Before規(guī)則

Happens-Before規(guī)則就是保證前面的一個操作的結(jié)果對后續(xù)操作是可見的。

它約束了編譯器的優(yōu)化行為,雖允許編譯器優(yōu)化,但是要求編譯器優(yōu)化后一定遵守Happens-Before規(guī)則:

規(guī)則一:程序的順序性規(guī)則

? 這條規(guī)則是指在一個線程中,按照程序順序,前面的操作 Happens-Before 于后續(xù)的任意操作。

這還是比較容易理解的,比如剛才那段示例代碼,按照程序的順序,第 6 行代碼 “x = 42;” Happens-Before 于第 7 行代碼 “v = true;”,這就是規(guī)則 1 的內(nèi)容,也比較符合單線程里面的思維:程序前面對某個變量的修改一定是對后續(xù)操作可見的。

規(guī)則二:volatile 變量規(guī)則

? 這條規(guī)則是指對一個 volatile 變量的寫操作, Happens-Before 于后續(xù)對這個 volatile 變量的讀操作,即對后面的讀操作可見。

規(guī)則三:傳遞性

? 這條規(guī)則是指如果A Happens-Before B,B Happens-Before C,那么 A Happens-Before C。

規(guī)則四:管程中鎖的規(guī)則

? 這條規(guī)則是指對一個鎖的解鎖Happens-Before于后續(xù)對這個鎖的加鎖。

? 管程是一種通用的同步原語,在Java中指的就是synchronized,synchronized是Java里對管程的實現(xiàn)。

tip: 在操作系統(tǒng)中,管程的定義如下: 管程是由一組數(shù)據(jù)以及定義在這組數(shù)據(jù)之上的對該組數(shù)據(jù)操作的操作組成的軟件模塊,稱之為管程。

基本特性:

1. 局部于管程的數(shù)據(jù)只能被局部于管程內(nèi)的過程所訪問。

2. 一個進程只有通過調(diào)用管程內(nèi)的過程才能進入管程訪問共享數(shù)據(jù)

3. 每次僅允許一個進程在管程中執(zhí)行某個內(nèi)部過程。

注意:由于管程是一個語言的成分,所以管程的互斥訪問完全由編譯程序在編譯時自動添加,無需程序員關(guān)注

? 管程中的鎖在Java是隱式實現(xiàn)的,加鎖以及釋放鎖都是編譯器幫我們實現(xiàn)的。

synchronized (this) { //此處自動加鎖
 // x是共享變量,初始值=10
 if (this.x < 12) {
   this.x = 12; 
 }  
} //此處自動解鎖

規(guī)則五:線程start()規(guī)則

? 這條是關(guān)于線程啟動的,指主線程A啟動子線程B后,子線程B能夠看到主線程在啟動子線程B前的操作。

規(guī)則六:join()規(guī)則

? 這條是關(guān)于線程等待的,它是指主線程A等待子線程B完成(主線程A通過調(diào)用子線程B的join()方法實現(xiàn)),當(dāng)子線程B完成后(主線程A中join()方法返回)

主線程能夠看到子線程的操作。這里的“看到”,指的是對共享變量的操作。

通過調(diào)用子線程B的join()方法實現(xiàn)),當(dāng)子線程B完成后(主線程A中join()方法返回)

主線程能夠看到子線程的操作。這里的“看到”,指的是對共享變量的操作。

到此這篇關(guān)于關(guān)于Java中的可見性和有序性問題的文章就介紹到這了,更多相關(guān)Java可見性和有序性內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 通過Java來測試JSON和Protocol Buffer的傳輸文件大小

    通過Java來測試JSON和Protocol Buffer的傳輸文件大小

    這篇文章主要介紹了通過Java來測試JSON和Protocol Buffer的傳輸文件大小,Protocol Buffer(文中簡稱Protobuffer)是谷歌開發(fā)的新的文件傳輸格式,需要的朋友可以參考下
    2015-12-12
  • java分形繪制科赫雪花曲線(科赫曲線)代碼分享

    java分形繪制科赫雪花曲線(科赫曲線)代碼分享

    部分與整體以某種形式相似的形,稱為分形,科赫曲線是一種外形像雪花的幾何曲線,所以又稱為雪花曲線,它是分形曲線中的一種,畫法如下
    2013-12-12
  • 關(guān)于國際化、OGNL表達式語言

    關(guān)于國際化、OGNL表達式語言

    本篇文章,小編為大家介紹關(guān)于國際化、OGNL表達式語言,有需要的朋友可以參考一下
    2013-04-04
  • Java利用Spire.XLS for Java實現(xiàn)自動化生成PDF文檔

    Java利用Spire.XLS for Java實現(xiàn)自動化生成PDF文檔

    在 Java 后端高效靈活地實現(xiàn) PDF 文檔的生成,常常是困擾開發(fā)者的一個痛點,本文將為您介紹如何利用 Spire.XLS for Java 輕松駕馭 Java 中的 PDF 文檔生成,感興趣的小伙伴可以了解下
    2026-02-02
  • Java中實現(xiàn)線程的超時中斷方法實例

    Java中實現(xiàn)線程的超時中斷方法實例

    之前在使用Java實現(xiàn)熔斷降級組件的時候,需要實現(xiàn)接口請求的超時中斷,通過查找相關(guān)資料了解了相關(guān)的方法,下面這篇文章主要給大家介紹了關(guān)于Java中實現(xiàn)線程的超時中斷的相關(guān)資料,需要的朋友可以參考下
    2018-06-06
  • Mac下卸載IntelliJ IDEA實現(xiàn)過程

    Mac下卸載IntelliJ IDEA實現(xiàn)過程

    本文介紹了Mac系統(tǒng)下徹底卸載IDEA的方法,包括刪除應(yīng)用程序文件、支持文件、設(shè)置文件、程序狀態(tài)文件、偏好設(shè)置數(shù)據(jù)、緩存文件、日志數(shù)據(jù)、其他相關(guān)文件等,最后提供了一鍵刪除命令,但需要注意確認(rèn)文件目錄情況
    2026-05-05
  • LambdaQueryWrapper與QueryWrapper的使用方式

    LambdaQueryWrapper與QueryWrapper的使用方式

    這篇文章主要介紹了LambdaQueryWrapper與QueryWrapper的使用方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • SpringBoot集成XXL-JOB實現(xiàn)任務(wù)管理全流程

    SpringBoot集成XXL-JOB實現(xiàn)任務(wù)管理全流程

    XXL-JOB 是一款輕量級分布式任務(wù)調(diào)度平臺,功能豐富、界面簡潔、易于擴展,本文介紹如何通過 Spring Boot 項目,使用 RestTemplate 和 Feign 的方式調(diào)用 XXL-JOB 后臺管理接口,實現(xiàn)任務(wù)的全生命周期管理,需要的朋友可以參考下
    2025-08-08
  • JAVA截取字符串的幾種常用方法

    JAVA截取字符串的幾種常用方法

    這篇文章主要給大家介紹了關(guān)于JAVA截取字符串的幾種常用方法, 在處理字符串的過程中有很多情況下會遇到需要截取字符串的情況,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2023-09-09
  • 使用IDEA打jar包的詳細圖文教程

    使用IDEA打jar包的詳細圖文教程

    JAR文件是一種壓縮文件,與常見的ZIP壓縮文件兼容,被稱為JAR包,下面這篇文章主要給大家介紹了關(guān)于使用IDEA打jar包的相關(guān)資料,文中通過圖文介紹的非常詳細,需要的朋友可以參考下
    2022-08-08

最新評論

吉木乃县| 乡宁县| 金乡县| 临高县| 滕州市| 东莞市| 麻栗坡县| 灌阳县| 河西区| 康保县| 九龙城区| 西乡县| 鹤庆县| 上杭县| 河西区| 青岛市| 北川| 江达县| 年辖:市辖区| 西安市| 邻水| 望奎县| 仲巴县| 安宁市| 右玉县| 商水县| 木兰县| 沂南县| 清苑县| 昌邑市| 英山县| 澳门| 西乡县| 福建省| 东城区| 武鸣县| 霍邱县| 澄迈县| 策勒县| 定远县| 莱西市|