欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java volatile四種內(nèi)存屏障的作用與生效機(jī)制原理詳解

 更新時間:2025年09月10日 11:15:36   作者:親愛的非洲野豬  
內(nèi)存屏障是處理器提供的一種指令,用于控制指令執(zhí)行順序和內(nèi)存可見性,在Java中,volatile關(guān)鍵字就是通過插入內(nèi)存屏障來實現(xiàn)其內(nèi)存語義的,下面我將詳細(xì)解釋四種內(nèi)存屏障的含義和工作原理,感興趣的朋友一起看看吧

在Java中,volatile關(guān)鍵字是一種輕量級的同步機(jī)制,用于確保變量的可見性和有序性。為了實現(xiàn)這些功能,Java虛擬機(jī)(JVM)在底層使用了內(nèi)存屏障(Memory Barrier),這些內(nèi)存屏障確保了在多線程環(huán)境下,對共享變量的讀寫操作的正確順序和可見性。

內(nèi)存屏障(Memory Barrier)是處理器提供的一種指令,用于控制指令執(zhí)行順序和內(nèi)存可見性。在Java中,volatile關(guān)鍵字就是通過插入內(nèi)存屏障來實現(xiàn)其內(nèi)存語義的。下面我將詳細(xì)解釋四種內(nèi)存屏障的含義和工作原理。

1. 四種基本內(nèi)存屏障

1.1 StoreStore屏障

作用

  • 確保屏障前的所有普通寫操作(store)完成并刷新到主內(nèi)存
  • 在屏障后的volatile寫操作之前執(zhí)行

生效機(jī)制

普通寫操作1
普通寫操作2
StoreStore屏障
volatile寫操作

實際效果:保證在volatile變量寫入前,所有之前的普通變量寫入都已經(jīng)完成并可見

1.2 StoreLoad屏障

作用

  • 確保屏障前的所有寫操作(包括volatile寫)完成并刷新到主內(nèi)存
  • 在屏障后的所有讀操作(包括volatile讀)之前執(zhí)行

生效機(jī)制

volatile寫操作
StoreLoad屏障
volatile讀操作/普通讀操作

實際效果:這是最"重量級"的屏障,會使該屏障之前的所有內(nèi)存訪問指令(存儲和裝載)完成之后,才執(zhí)行該屏障之后的內(nèi)存訪問指令

1.3 LoadLoad屏障

作用

  • 確保屏障前的所有讀操作(load)完成
  • 在屏障后的所有讀操作之前執(zhí)行

生效機(jī)制

volatile讀操作
LoadLoad屏障
普通讀操作/volatile讀操作

實際效果:保證在讀取后續(xù)變量前,先完成對volatile變量的讀取

1.4 LoadStore屏障

作用

  • 確保屏障前的所有讀操作(load)完成
  • 在屏障后的所有寫操作之前執(zhí)行

生效機(jī)制

volatile讀操作
LoadStore屏障
普通寫操作/volatile寫操作

實際效果:保證在寫入任何變量前,先完成對volatile變量的讀取

2. 內(nèi)存屏障在volatile中的具體應(yīng)用

2.1 volatile寫操作的內(nèi)存屏障插入

編譯器會在volatile寫操作前后插入以下屏障:

[普通寫操作]
StoreStore屏障
[volatile寫操作]
StoreLoad屏障

示例

x = 42;       // 普通寫
y = true;     // volatile寫

實際生成的指令序列:

store x, 42
StoreStore屏障
store y, true
StoreLoad屏障

2.2 volatile讀操作的內(nèi)存屏障插入

編譯器會在volatile讀操作前后插入以下屏障:

LoadLoad屏障
[volatile讀操作]
LoadStore屏障

示例

if (y) {      // volatile讀
    z = x;    // 普通讀和普通寫
}

實際生成的指令序列:

LoadLoad屏障
load y
LoadStore屏障
load x
store z, x

3. 內(nèi)存屏障如何保證happens-before關(guān)系

內(nèi)存屏障通過限制處理器和編譯器的重排序來建立happens-before關(guān)系:

  1. StoreStore屏障:確保volatile寫之前的普通寫操作happens-before volatile寫
  2. StoreLoad屏障:確保volatile寫happens-before后續(xù)的volatile讀/寫
  3. LoadLoad屏障:確保volatile讀happens-before后續(xù)的所有讀操作
  4. LoadStore屏障:確保volatile讀happens-before后續(xù)的所有寫操作

4. 實際處理器中的實現(xiàn)差異

不同處理器架構(gòu)對內(nèi)存屏障的支持不同:

  • x86/64:原生支持較強(qiáng)的內(nèi)存模型,只有StoreLoad屏障是真正有作用的
  • ARM/PowerPC:需要顯式使用所有四種屏障
  • JVM:會根據(jù)目標(biāo)平臺將Java內(nèi)存屏障映射到具體的處理器指令

例如,在x86上:

  • StoreStore屏障通常實現(xiàn)為空操作(no-op)
  • StoreLoad屏障實現(xiàn)為mfence指令或lock前綴指令

5. 示例分析

class ReorderingExample {
    int x = 0;
    volatile boolean v = false;
    void writer() {
        x = 42;      // 普通寫
        v = true;    // volatile寫
    }
    void reader() {
        if (v) {     // volatile讀
            System.out.println(x); // 普通讀
        }
    }
}

內(nèi)存屏障插入后的執(zhí)行順序保證

  • 在writer()中:
    • x = 42v = true之間插入StoreStore屏障
    • 確保x的寫入在v的寫入前完成并可見
  • 在reader()中:
    • if (v)前插入LoadLoad屏障
    • System.out.println(x)前插入LoadStore屏障
    • 確保讀取v后才讀取x,且讀取的是最新值

6. 為什么需要四種屏障

四種屏障對應(yīng)不同的讀寫組合,提供了細(xì)粒度的控制:

  1. StoreStore:寫→寫順序
  2. StoreLoad:寫→讀順序(最常用且開銷最大)
  3. LoadLoad:讀→讀順序
  4. LoadStore:讀→寫順序

這種細(xì)粒度控制允許JVM在不同架構(gòu)上實現(xiàn)最優(yōu)性能,只在必要的地方插入必要的屏障。

7. 總結(jié)

四種內(nèi)存屏障共同作用,確保了:

  • volatile寫的可見性(StoreStore + StoreLoad)
  • volatile讀的 freshness(LoadLoad + LoadStore)
  • 防止不合理的重排序
  • 建立正確的happens-before關(guān)系

以下是四種內(nèi)存屏障的詳細(xì)對比表格,展示了它們的特點、作用和區(qū)別:

屏障類型插入位置保證的操作順序主要作用典型使用場景開銷級別
StoreStorevolatile寫操作之前普通寫 → volatile寫確保volatile寫之前的所有普通寫操作對其它處理器可見volatile寫前的普通變量寫入
StoreLoadvolatile寫操作之后volatile寫 → 后續(xù)所有讀確保volatile寫對所有處理器可見后,才能執(zhí)行后續(xù)的讀操作volatile寫后可能的讀操作
LoadLoadvolatile讀操作之前volatile讀 → 后續(xù)所有讀確保先完成volatile讀,才能進(jìn)行后續(xù)的讀操作volatile讀后的普通變量讀取
LoadStorevolatile讀操作之后volatile讀 → 后續(xù)所有寫確保先完成volatile讀,才能進(jìn)行后續(xù)的寫操作volatile讀后的普通變量寫入

詳細(xì)特性對比

特性StoreStoreStoreLoadLoadLoadLoadStore
防止的重排序類型寫-寫重排序寫-讀重排序讀-讀重排序讀-寫重排序
保證的可見性使屏障前的寫對所有線程可見使屏障前的寫對所有線程可見確保讀取最新值確保基于最新值進(jìn)行寫入
對應(yīng)CPU指令通常為no-op(x86)
sfence(某些架構(gòu))
mfence(x86)
sync(PowerPC)
lfence(某些架構(gòu))通常組合使用
發(fā)生頻率每次volatile寫前每次volatile寫后每次volatile讀前每次volatile讀后
影響范圍僅影響寫操作順序影響寫后所有讀操作僅影響讀操作順序影響讀后所有寫操作
性能影響較小較大中等中等

實際效果示例對比

屏障類型代碼示例 (屏障位置)保證的效果
StoreStorex=1; [SS]; v=2;其他線程看到v=2時,必定能看到x=1
StoreLoadv=1; [SL]; if(x)...執(zhí)行x的讀取時,v=1的寫入已經(jīng)全局可見
LoadLoad[LL]; if(v)...; tmp=x;讀取x時,v的讀取已經(jīng)完成且是最新值
LoadStoreif(v)...; [LS]; x=1;寫入x=1時,已經(jīng)基于最新的v值進(jìn)行了判斷

不同處理器架構(gòu)上的表現(xiàn)

屏障類型x86/64實現(xiàn)ARM實現(xiàn)PowerPC實現(xiàn)
StoreStore通常不需要(隱式保證)dmb ishstlwsync
StoreLoadmfence指令dmb ishsync
LoadLoad通常不需要(隱式保證)dmb ishldlwsync
LoadStore通常不需要(隱式保證)dmb ishlwsync

這個表格總結(jié)了四種內(nèi)存屏障的關(guān)鍵區(qū)別,理解這些差異對于編寫正確的高性能并發(fā)程序非常重要。實際開發(fā)中,雖然我們很少直接操作這些屏障(它們由JVM自動插入),但了解其原理有助于診斷并發(fā)問題和優(yōu)化性能。

理解這些內(nèi)存屏障的工作原理,有助于深入理解Java內(nèi)存模型和并發(fā)編程中的各種可見性、有序性問題。

到此這篇關(guān)于Java volatile 內(nèi)存屏障詳解:四種內(nèi)存屏障的作用與生效機(jī)制的文章就介紹到這了,更多相關(guān)Java volatile 內(nèi)存屏障內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 升級springboot3之自動配置導(dǎo)入失效問題及解決

    升級springboot3之自動配置導(dǎo)入失效問題及解決

    這篇文章主要介紹了升級springboot3之自動配置導(dǎo)入失效問題及解決,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • Mac使用Idea配置傳統(tǒng)SSM項目(非maven項目)

    Mac使用Idea配置傳統(tǒng)SSM項目(非maven項目)

    本文主要介紹了Mac使用Idea配置傳統(tǒng)SSM項目(非maven項目),將展示如何設(shè)置項目結(jié)構(gòu)、添加依賴關(guān)系等,具有一定的參考價值,感興趣的可以了解一下
    2024-01-01
  • 詳解Java中常見語法糖的使用

    詳解Java中常見語法糖的使用

    語法糖(Syntactic Sugar),也稱糖衣語法,是由英國計算機(jī)學(xué)家 Peter.J.Landin 發(fā)明的一個術(shù)語,指在計算機(jī)語言中添加的某種語法,本文主要為大家分享了12個java中常見的語法糖,感興趣的小伙伴可以了解下
    2023-11-11
  • Spring?Boot?集成PageHelper的使用方法

    Spring?Boot?集成PageHelper的使用方法

    這篇文章主要介紹了Spring?Boot?集成PageHelper的使用方法,文章內(nèi)容圍繞主題展開詳細(xì)介紹,需要的小伙伴可以參考一下,希望對你的學(xué)習(xí)有所幫助
    2022-04-04
  • java實現(xiàn)的密碼強(qiáng)度檢測功能完整示例

    java實現(xiàn)的密碼強(qiáng)度檢測功能完整示例

    這篇文章主要介紹了java實現(xiàn)的密碼強(qiáng)度檢測功能,結(jié)合完整實例形式分析了java針對密碼強(qiáng)度檢測相關(guān)的字符串遍歷、判斷,以及輸出密碼強(qiáng)度等級相關(guān)操作技巧,需要的朋友可以參考下
    2019-06-06
  • MyBatis中的配置文件詳解

    MyBatis中的配置文件詳解

    在?MyBatis?中,配置文件分為?全局配置文件(核心配置文件)和映射配置文件,本文給大家介紹MyBatis中的配置文件相關(guān)知識,感興趣的朋友一起看看吧
    2023-10-10
  • Java數(shù)據(jù)類型(八種基本數(shù)據(jù)類型+四種引用類型)以及數(shù)據(jù)類型轉(zhuǎn)換

    Java數(shù)據(jù)類型(八種基本數(shù)據(jù)類型+四種引用類型)以及數(shù)據(jù)類型轉(zhuǎn)換

    java中除了基本數(shù)據(jù)類型之外,剩下的都是引用數(shù)據(jù)類型,下面這篇文章主要給大家介紹了關(guān)于Java數(shù)據(jù)類型(八種基本數(shù)據(jù)類型?+?四種引用類型)以及數(shù)據(jù)類型轉(zhuǎn)換的相關(guān)資料,需要的朋友可以參考下
    2024-04-04
  • java使用FuncGPT慧函數(shù)對Mybatis進(jìn)行一對一查詢映射處理

    java使用FuncGPT慧函數(shù)對Mybatis進(jìn)行一對一查詢映射處理

    這篇文章主要介紹了java使用FuncGPT慧函數(shù)對Mybatis進(jìn)行一對一查詢映射處理,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • Spring 配置文件字段注入到List、Map

    Spring 配置文件字段注入到List、Map

    這篇文章主要介紹了Spring 配置文件字段注入到List、Map,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • Java中Date和Calendar常用方法

    Java中Date和Calendar常用方法

    這篇文章主要為大家詳細(xì)介紹了Java中Date和Calendar常用用法,感興趣的小伙伴們可以參考一下
    2016-09-09

最新評論