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

Java內(nèi)存模型及其作用詳解

 更新時間:2024年04月03日 10:45:24   作者:牽著貓散步的鼠鼠  
在現(xiàn)代計算機系統(tǒng)中,尤其是多處理器架構(gòu)下,每個處理器都有自己的高速緩存,而主內(nèi)存(RAM)是所有處理器共享的數(shù)據(jù)存儲區(qū)域,這篇文章主要介紹了深入理解Java內(nèi)存模型及其作用,需要的朋友可以參考下

1.前言

當(dāng)問到 Java 內(nèi)存模型的時候,一定要注意,Java 內(nèi)存模型(Java Memory Model,JMM)它和 JVM 內(nèi)存布局(JVM 運行時數(shù)據(jù)區(qū)域)是不一樣的,它們是兩個完全不同的概念。

2.為什么要有 Java 內(nèi)存模型?

Java 內(nèi)存模型存在的原因在于解決多線程環(huán)境下并發(fā)執(zhí)行時的內(nèi)存可見性和一致性問題。在現(xiàn)代計算機系統(tǒng)中,尤其是多處理器架構(gòu)下,每個處理器都有自己的高速緩存,而主內(nèi)存(RAM)是所有處理器共享的數(shù)據(jù)存儲區(qū)域。當(dāng)多個線程同時訪問和修改同一塊共享數(shù)據(jù)時,如果沒有適當(dāng)?shù)耐綑C制,就可能導(dǎo)致以下問題:

  • 可見性:一個線程對共享變量所做的修改可能不會立即反映到另一個線程的視角中,因為這些修改可能只存在于本地緩存中,并未刷新回主內(nèi)存。
  • 有序性:編譯器和處理器為了優(yōu)化性能,可能會對指令進行重排序,這可能導(dǎo)致程序在單線程環(huán)境中看似按照源代碼順序執(zhí)行,但在多線程環(huán)境中的實際執(zhí)行順序卻與預(yù)期不同。
  • 原子性:即使是最簡單的讀取或賦值操作,在硬件層面也不一定保證是原子性的,即在沒有同步的情況下,多線程下可能看到操作只執(zhí)行了一部分的結(jié)果。

Java 內(nèi)存模型通過定義一套規(guī)則來規(guī)范并限制編譯器、運行時以及處理器對內(nèi)存訪問的重排序行為,確保了多線程間的交互具有明確的語義。它規(guī)定了共享變量的訪問規(guī)則、提供了 happens-before 原則以及 volatile 關(guān)鍵字、synchronized 等工具來實現(xiàn)內(nèi)存可見性和一致性的保障。這樣,程序員在編寫并發(fā)代碼時,可以依據(jù)這些規(guī)則來確保代碼的正確執(zhí)行,從而避免由于多線程帶來的不確定性和錯誤。

如果沒有 Java 內(nèi)存模型就會出現(xiàn)以下兩大問題:

  • CPU 和 內(nèi)存一致性問題。
  • 指令重排序問題。

具體內(nèi)容如下。

2.1 一致性問題

要講明白緩存一致性問題,要從計算機的內(nèi)存結(jié)構(gòu)說起,它的結(jié)構(gòu)是這樣的: 

 所以從上面可以看出計算機的重要組成部分包含以下內(nèi)容:

  • CPU
  • CPU 寄存器:也叫 L1 緩存,一級緩存。
  • CPU 高速緩存:也叫 L2 緩存,二級緩存。
  • (主)內(nèi)存

當(dāng)然,部分高端機器還有 L3 三級緩存。

由于主內(nèi)存與 CPU 處理器的運算能力之間有數(shù)量級的差距,所以在傳統(tǒng)計算機內(nèi)存架構(gòu)中會引入高速緩存(L2)來作為主存和處理器之間的緩沖,CPU 將常用的數(shù)據(jù)放在高速緩存中,運算結(jié)束后 CPU 再講運算結(jié)果同步到主內(nèi)存中,這樣就會導(dǎo)致多個線程在進行操作和同步時,導(dǎo)致 CPU 緩存和主內(nèi)存數(shù)據(jù)不一致的問題。

2.2 重排序問題

由于有 JIT(Just In Time,即時編譯)技術(shù)的存在,它可能會對代碼進行優(yōu)化,比如將原本執(zhí)行順序為 a -> b -> c 的流程,“優(yōu)化”成 a -> c -> b 了,但這樣優(yōu)化之后,可能會導(dǎo)致我們的程序在某些場景執(zhí)行出錯,比如單例模式雙重效驗鎖的場景,這就是典型的好心辦壞事的事例。

3.Java 內(nèi)存模型的定義

Java 內(nèi)存模型(Java Memory Model,簡稱 JMM)是一種規(guī)范,它定義了 Java 虛擬機(JVM)在計算機內(nèi)存(RAM)中的工作方式,即規(guī)范了 Java 虛擬機與計算機內(nèi)存之間是如何協(xié)同工作的。具體來說,它規(guī)定了一個線程如何和何時可以看到其他線程修改過的共享變量的值,以及在必須時如何同步地訪問共享變量。

4.規(guī)范內(nèi)容

Java 內(nèi)存模型主要包括以下內(nèi)容:

  • 主內(nèi)存(Main Memory):所有線程共享的內(nèi)存區(qū)域,包含了對象的字段、方法和運行時常量池等數(shù)據(jù)。
  • 工作內(nèi)存(Working Memory):每個線程擁有自己的工作內(nèi)存,用于存儲主內(nèi)存中的數(shù)據(jù)的副本,線程只能直接操作工作內(nèi)存中的數(shù)據(jù)。
  • 內(nèi)存間交互操作:線程通過讀取和寫入操作與主內(nèi)存進行交互。讀操作將數(shù)據(jù)從主內(nèi)存復(fù)制到工作內(nèi)存,寫操作將修改后的數(shù)據(jù)刷新到主內(nèi)存。
  • 原子性(Atomicity):JMM 保證基本數(shù)據(jù)類型(如 int、long)的讀寫操作具有原子性,即不會被其他線程干擾,保證操作的完整性。
  • 可見性(Visibility):JMM 確保一個線程對共享變量的修改對其他線程可見。這意味著一個線程在工作內(nèi)存中修改了數(shù)據(jù)后,必須將最新的數(shù)據(jù)刷新到主內(nèi)存,以便其他線程可以讀取到更新后的數(shù)據(jù)。
  • 有序性(Ordering):JMM 保證程序的執(zhí)行順序按照一定的規(guī)則進行,不會出現(xiàn)隨機的重排序現(xiàn)象。這包括了編譯器重排序、處理器重排序和內(nèi)存重排序等。

Java 內(nèi)存模型通過以上規(guī)則和語義,提供了一種統(tǒng)一的內(nèi)存訪問方式,使得多線程程序的行為可預(yù)測、可理解,并幫助開發(fā)者編寫正確和高效的多線程代碼。開發(fā)者可以利用 JMM 提供的同步機制(如關(guān)鍵字 volatile、synchronized、Lock 等)來實現(xiàn)線程之間的同步和通信,以確保線程安全和數(shù)據(jù)一致性。

內(nèi)存模型的簡單執(zhí)行示例圖如下: 

4.1 主內(nèi)存和工作內(nèi)存交互規(guī)范

為了更好的控制主內(nèi)存和本地內(nèi)存的交互,Java 內(nèi)存模型定義了八種操作來實現(xiàn)(以下內(nèi)容只需要簡單了解即可):

  • lock(鎖定):作用于主內(nèi)存的變量,把一個變量標(biāo)識為一條線程獨占狀態(tài)。
  • unlock(解鎖):作用于主內(nèi)存變量,把一個處于鎖定狀態(tài)的變量釋放出來,釋放后的變量才可以被其他線程鎖定。
  • read(讀?。鹤饔糜谥鲀?nèi)存變量,把一個變量值從主內(nèi)存?zhèn)鬏數(shù)骄€程的工作內(nèi)存中,以便隨后的 load 動作使用
  • load(載入):作用于工作內(nèi)存的變量,它把 read 操作從主內(nèi)存中得到的變量值放入工作內(nèi)存的變量副本中。
  • use(使用):作用于工作內(nèi)存的變量,把工作內(nèi)存中的一個變量值傳遞給執(zhí)行引擎,每當(dāng)虛擬機遇到一個需要使用變量的值的字節(jié)碼指令時將會執(zhí)行這個操作。
  • assign(賦值):作用于工作內(nèi)存的變量,它把一個從執(zhí)行引擎接收到的值賦值給工作內(nèi)存的變量,每當(dāng)虛擬機遇到一個給變量賦值的字節(jié)碼指令時執(zhí)行這個操作。
  • store(存儲):作用于工作內(nèi)存的變量,把工作內(nèi)存中的一個變量的值傳送到主內(nèi)存中,以便隨后的write的操作。
  • write(寫入):作用于主內(nèi)存的變量,它把 store 操作從工作內(nèi)存中一個變量的值傳送到主內(nèi)存的變量中。

PS:工作內(nèi)存也就是本地內(nèi)存的意思。

4.2 什么是 happens-before 原則?

happens-before(先行發(fā)生)原則是 Java 內(nèi)存模型中定義的用于保證多線程環(huán)境下操作執(zhí)行順序和可見性的一種重要手段。

舉個例子來說,例如 A happens-before B,也就是 A 線程早于 B 線程執(zhí)行,那么 A happens-before B 可以保障以下兩項內(nèi)容:

  • 可見性:B 讀取到 A 最新修改的值(通過內(nèi)存屏障)。
  • 順序性:編譯器優(yōu)化、處理器重排序等因素不會影響先執(zhí)行 A 再執(zhí)行 B 的順序。

到此這篇關(guān)于深入理解Java內(nèi)存模型及其作用的文章就介紹到這了,更多相關(guān)Java內(nèi)存模型內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java之抽象類和繼承抽象類解讀

    java之抽象類和繼承抽象類解讀

    這篇文章主要介紹了java之抽象類和繼承抽象類,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • 一文詳解如何查看jdk版本及安裝路徑

    一文詳解如何查看jdk版本及安裝路徑

    這篇文章主要給大家介紹了關(guān)于如何查看jdk版本及安裝路徑的相關(guān)資料,JDK是Java語言的軟件開發(fā)工具包,主要用于移動設(shè)備、嵌入式設(shè)備上的java應(yīng)用程序,文中通過圖文介紹的非常詳細,需要的朋友可以參考下
    2023-10-10
  • SpringBoot結(jié)合JWT實現(xiàn)用戶登錄、注冊、鑒權(quán)

    SpringBoot結(jié)合JWT實現(xiàn)用戶登錄、注冊、鑒權(quán)

    用戶登錄、注冊及鑒權(quán)是我們基本所有系統(tǒng)必備的,也是很核心重要的一塊,本文主要介紹了SpringBoot結(jié)合JWT實現(xiàn)用戶登錄、注冊、鑒權(quán),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2023-05-05
  • 詳解SpringBoot?統(tǒng)一后端返回格式的方法

    詳解SpringBoot?統(tǒng)一后端返回格式的方法

    今天我們來聊一聊在基于SpringBoot前后端分離開發(fā)模式下,如何友好的返回統(tǒng)一的標(biāo)準格式以及如何優(yōu)雅的處理全局異常,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2022-05-05
  • java并發(fā)編程之進程和線程調(diào)度基礎(chǔ)詳解

    java并發(fā)編程之進程和線程調(diào)度基礎(chǔ)詳解

    這篇文章主要介紹了java并發(fā)編程之進程和線程調(diào)度基礎(chǔ),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • IDEA報錯“Command line is too long”的解決步驟

    IDEA報錯“Command line is too long”的解決步驟

    這篇文章解釋了在使用SpringBoot項目時,因啟動命令行過長導(dǎo)致啟動失敗的問題,并提供了兩種解決方案:JARmanifest和classpathfile,推薦使用JARmanifest,如果遇到類加載問題可;同時提供了修改默認模板的方法,以避免以后的新項目再次遇到此問題,需要的朋友可以參考下
    2026-05-05
  • Springboot+mybatis-plus+注解實現(xiàn)數(shù)據(jù)權(quán)限隔離

    Springboot+mybatis-plus+注解實現(xiàn)數(shù)據(jù)權(quán)限隔離

    本文將結(jié)合實例代碼,介紹Springboot+mybatis-plus+注解實現(xiàn)數(shù)據(jù)權(quán)限隔離,文中通過示例代碼介紹的非常詳細,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-07-07
  • MyBatisPlus自定義SQL的實現(xiàn)

    MyBatisPlus自定義SQL的實現(xiàn)

    MyBatisPlus提供了自定義SQL功能,允許開發(fā)者在Mapper接口中定義方法,并通過XML文件或注解編寫SQL語句,本文詳解了如何在MP中使用自定義SQL,感興趣的可以了解一下
    2024-09-09
  • 基于Spring Security前后端分離的權(quán)限控制系統(tǒng)問題

    基于Spring Security前后端分離的權(quán)限控制系統(tǒng)問題

    本文給大家分享基于Spring Security前后端分離的權(quán)限控制系統(tǒng)問題,需要了解權(quán)限如何加載,權(quán)限匹配規(guī)則和登錄的實現(xiàn)代碼,對Spring Security權(quán)限控制系統(tǒng)相關(guān)知識感興趣的朋友一起看看吧
    2021-06-06
  • 詳解Java數(shù)組的定義和聲明方法

    詳解Java數(shù)組的定義和聲明方法

    在Java開發(fā)中,數(shù)組是最常用的數(shù)據(jù)結(jié)構(gòu)之一,因此,深入了解Java數(shù)組的定義和聲明是非常必要的,本文將詳細介紹Java數(shù)組的定義和聲明方法,以及其在實際開發(fā)中的應(yīng)用場景、優(yōu)缺點等方面,需要的朋友可以參考下
    2023-11-11

最新評論

东光县| 宁德市| 乐昌市| 新乡县| 伊通| 吴旗县| 汤阴县| 东乡县| 昌邑市| 双流县| 和静县| 博客| 大庆市| 永清县| 伊宁县| 龙川县| 弥勒县| 贵定县| 上高县| 维西| 太仆寺旗| 鄄城县| 平湖市| 马鞍山市| 新龙县| 庆云县| 云和县| 武宁县| 吕梁市| 务川| 白玉县| 静海县| 镇坪县| 桃江县| 三门峡市| 郧西县| 安宁市| 平谷区| 嘉黎县| 舞钢市| 长子县|