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

java中volatile關(guān)鍵字解釋說明

 更新時間:2026年01月26日 11:22:41   作者:菜雞上道  
volatile是Java中的一個關(guān)鍵字,用于修飾變量,保證其可見性和禁止指令重排序,但不保證原子性,下面我們從原理層面詳細(xì)解析volatile 的工作機(jī)制,感興趣的朋友跟隨小編一起看看吧

在 Java 中,volatile 是一個輕量級的同步機(jī)制關(guān)鍵字,用于修飾字段(變量),其核心作用是:

保證變量的“可見性”和“禁止指令重排序”,但不保證原子性。

下面我們從原理層面詳細(xì)解析 volatile 的工作機(jī)制。

一、三大特性:可見性、有序性、原子性

特性volatile 是否支持說明
可見性(Visibility)? 支持一個線程修改了 volatile 變量,其他線程能立即看到最新值
有序性(Ordering)? 支持(禁止重排序)JVM 和 CPU 不會對 volatile 讀寫進(jìn)行重排序優(yōu)化
原子性(Atomicity)? 不支持(除 long/double 的簡單讀寫)i++ 這類復(fù)合操作不是原子的

二、volatile 的底層原理(基于內(nèi)存模型)

1.Java 內(nèi)存模型(JMM)背景

  • 每個線程有自己的工作內(nèi)存(緩存、寄存器)
  • 所有變量存儲在主內(nèi)存
  • 線程對變量的操作必須先從主內(nèi)存拷貝到工作內(nèi)存,操作后再寫回

問題:如果沒有同步機(jī)制,線程 A 修改了變量,線程 B 可能永遠(yuǎn)看不到新值(因?yàn)樽x的是本地緩存)。

2.volatile 如何解決可見性?

當(dāng)一個字段被聲明為 volatile

  • 寫操作:線程必須將該變量的最新值立即刷新到主內(nèi)存
  • 讀操作:線程必須從主內(nèi)存重新讀取該變量的值,而不是使用本地緩存

這相當(dāng)于每次讀寫都強(qiáng)制與主內(nèi)存同步。

3.內(nèi)存屏障(Memory Barrier / Memory Fence)

JVM 在編譯 volatile 讀寫時,會插入內(nèi)存屏障指令,實(shí)現(xiàn)兩個效果:

(1)禁止指令重排序

  • 在 volatile 寫之前的操作,不能重排到寫之后
  • 在 volatile 讀之后的操作,不能重排到讀之前

例如:

// 假設(shè) flag 是 volatile
a = 1;          // 普通寫
flag = true;    // volatile 寫

a = 1 一定發(fā)生在 flag = true 之前,不會被重排序。

(2)強(qiáng)制刷新緩存

  • 寫屏障(Store Barrier):確保寫入主內(nèi)存
  • 讀屏障(Load Barrier):確保從主內(nèi)存加載

這些屏障由 JVM 根據(jù)不同 CPU 架構(gòu)(x86、ARM 等)生成對應(yīng)的底層指令(如 lock 前綴指令)。

三、典型應(yīng)用場景

? 場景 1:狀態(tài)標(biāo)志位(最常見)

public class TaskRunner {
    private volatile boolean running = true;
    public void stop() {
        running = false; // 其他線程能立即看到
    }
    public void run() {
        while (running) {
            // do work
        }
    }
}

若不用 volatilerun() 方法可能因讀取本地緩存而永遠(yuǎn)無法退出。

? 場景 2:單例模式中的雙重檢查鎖定(DCL)

public class Singleton {
    private static volatile Singleton instance;
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton(); // 防止重排序?qū)е挛闯跏蓟瓿删捅灰?
                }
            }
        }
        return instance;
    }
}

如果沒有 volatile,new Singleton() 的三步(分配內(nèi)存、初始化、賦值)可能被重排序?yàn)?ldquo;分配 → 賦值 → 初始化”,導(dǎo)致其他線程拿到未初始化的對象。

? 不適用場景:復(fù)合操作(非原子)

private volatile int count = 0;
public void increment() {
    count++; // 實(shí)際是:讀取 count → +1 → 寫回,非原子!
}

此時應(yīng)使用 AtomicInteger 或加鎖。

四、與 synchronized 的區(qū)別

特性volatilesynchronized
保證可見性??
保證原子性?(除簡單讀寫)?
保證有序性?(禁止重排序)?(隱式包含)
性能開銷低(無鎖)較高(涉及 Monitor 鎖)
適用范圍僅變量方法/代碼塊/變量

volatilesynchronized 的輕量替代方案,但功能更弱。

五、補(bǔ)充:long 和 double 的特殊性

Java 規(guī)范規(guī)定:

  • 非 volatile 的 long/double,讀寫可能被拆分為兩個 32 位操作(非原子)
  • volatile 的 long/double,JVM 保證讀寫是原子的(64 位一次性操作)

總結(jié)

volatile 的核心原理是:

  1. 通過內(nèi)存屏障實(shí)現(xiàn)變量的可見性;
  2. 禁止編譯器和處理器重排序,保證有序性;
  3. 不提供原子性,不能用于復(fù)合操作。

? 適用條件

當(dāng)一個變量被多個線程訪問,且滿足:

  • 寫操作不依賴當(dāng)前值(如 flag = true
  • 或者只有一個線程寫,其他線程只讀

否則,請使用 synchronized、ReentrantLockjava.util.concurrent.atomic 包中的原子類。

如需進(jìn)一步了解內(nèi)存屏障或 JMM 模型,也可以繼續(xù)提問!

到此這篇關(guān)于java中volatile關(guān)鍵字解釋說明的文章就介紹到這了,更多相關(guān)java volatile關(guān)鍵字內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • MyBatis的xml中字符串類型判空與非字符串類型判空處理方式(最新整理)

    MyBatis的xml中字符串類型判空與非字符串類型判空處理方式(最新整理)

    本文給大家介紹MyBatis的xml中字符串類型判空與非字符串類型判空處理方式,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2025-08-08
  • Spring集成MyBatis框架

    Spring集成MyBatis框架

    本文主要介紹了Spring集成MyBatis的配置和使用,項(xiàng)目基于Maven構(gòu)建,連接Mysql數(shù)據(jù)庫。下面跟著小編一起來看下吧
    2017-02-02
  • @Cacheable 拼接key的操作

    @Cacheable 拼接key的操作

    這篇文章主要介紹了@Cacheable 拼接key的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • SpringBoot項(xiàng)目中如何實(shí)現(xiàn)MySQL讀寫分離詳解

    SpringBoot項(xiàng)目中如何實(shí)現(xiàn)MySQL讀寫分離詳解

    在高并發(fā)下需要對應(yīng)用進(jìn)行讀寫分離,配置多數(shù)據(jù)源,即寫操作走主庫,讀操作則走從庫,主從數(shù)據(jù)庫負(fù)責(zé)各自的讀和寫,緩解了鎖的爭用,提高了讀取性能,這篇文章主要給大家介紹了關(guān)于SpringBoot項(xiàng)目中如何實(shí)現(xiàn)MySQL讀寫分離的相關(guān)資料,需要的朋友可以參考下
    2022-07-07
  • RestTemplate對HttpClient的適配源碼解讀

    RestTemplate對HttpClient的適配源碼解讀

    這篇文章主要為大家介紹了RestTemplate對HttpClient的適配源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • 詳解Java JDK動態(tài)代理

    詳解Java JDK動態(tài)代理

    這篇文章主要介紹了Java JDK動態(tài)代理的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)Java 代理的有關(guān)知識,感興趣的朋友可以了解下
    2020-08-08
  • Spring?Cloud?Eureka(全面解析)?大白話

    Spring?Cloud?Eureka(全面解析)?大白話

    這篇文章主要介紹了Spring?Cloud?Eureka(全面解析)?大白話,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Java使用策略模式解決商場促銷商品問題示例

    Java使用策略模式解決商場促銷商品問題示例

    這篇文章主要介紹了Java使用策略模式解決商場促銷商品問題,簡單描述了策略模式的概念、原理,并結(jié)合實(shí)例形式分析了Java基于策略模式解決商品促銷問題的相關(guān)操作技巧,需要的朋友可以參考下
    2018-05-05
  • 深入了解Springboot核心知識點(diǎn)之?dāng)?shù)據(jù)訪問配置

    深入了解Springboot核心知識點(diǎn)之?dāng)?shù)據(jù)訪問配置

    這篇文章主要為大家介紹了Springboot核心知識點(diǎn)中的數(shù)據(jù)訪問配置,文中的示例代碼講解詳細(xì),對我們了解SpringBoot有一定幫助,快跟隨小編一起學(xué)習(xí)一下吧
    2021-12-12
  • RocketMQ中消費(fèi)者的消費(fèi)進(jìn)度管理

    RocketMQ中消費(fèi)者的消費(fèi)進(jìn)度管理

    這篇文章主要介紹了RocketMQ中消費(fèi)者的消費(fèi)進(jìn)度管理,業(yè)務(wù)實(shí)現(xiàn)消費(fèi)回調(diào)的時候,當(dāng)且僅當(dāng)此回調(diào)函數(shù)返回ConsumeConcurrentlyStatus.CONSUME_SUCCESS ,RocketMQ才會認(rèn)為這批消息(默認(rèn)是1條)是消費(fèi)完成的,需要的朋友可以參考下
    2023-10-10

最新評論

琼海市| 安吉县| 沭阳县| 凤山县| 乌审旗| 东辽县| 宁海县| 阿拉善盟| 丹凤县| 蛟河市| 昔阳县| 和林格尔县| 专栏| 吉隆县| 迁西县| 六盘水市| 宣化县| 金沙县| 江达县| 平昌县| 淮阳县| 项城市| 兴隆县| 盐边县| 永清县| 双牌县| 分宜县| 临猗县| 宝丰县| 江阴市| 蓬溪县| 扶余县| 竹山县| 白水县| 岳阳市| 太仓市| 襄樊市| 玉门市| 鹤壁市| 金沙县| 荃湾区|