亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java volatile的幾種使用場景分析

 更新時(shí)間:2024年03月27日 09:24:05   作者:大明哥_  
volatile 是一種輕量級(jí)的同步機(jī)制,它能保證共享變量的可見性,同時(shí)禁止重排序保證了操作的有序性,但是它無法保證原子性,本文給大家總結(jié)了Java olatile的使用場景有哪些,并通過代碼示例講解的非常詳細(xì),需要的朋友可以參考下

回答

volatile 是一種輕量級(jí)的同步機(jī)制,它能保證共享變量的可見性,同時(shí)禁止重排序保證了操作的有序性,但是它無法保證原子性。所以使用 volatile 必須要滿足這兩個(gè)條件:

  • 寫入變量不依賴當(dāng)前值。
  • 變量不參與與其他變量的不變性條件。

volatile 比較適合多個(gè)線程讀,一個(gè)線程寫的場合,典型的場景有如下幾個(gè):

  • 狀態(tài)標(biāo)志
  • 重檢查鎖定的單例模式
  • 開銷較低的“讀-寫鎖”策略

詳解

volatile 使用條件

要想正確安全地使用 volatile ,必須要具備這兩個(gè)條件:

  • 寫入變量不依賴當(dāng)前值:變量的新值不能依賴于之前的舊值。如果變量的當(dāng)前值與新值之間存在依賴關(guān)系,那么僅使用 volatile 是不夠的,因?yàn)樗荒鼙WC一系列操作的原子性。比如 i++。
  • 變量不參與與其他變量的不變性條件:如果一個(gè)變量是與其他變量共同參與不變性條件的一部分,那么簡單地聲明變量為 volatile 是不夠的。

第一個(gè)條件很好理解,第二個(gè)條件這里需要解釋下。

“變量不參與與其他變量的不變性條件”,這里的“不變性條件”指的是一個(gè)或多個(gè)變量在程序執(zhí)行過程中需要保持的條件或關(guān)系,以確保程序的正確性。假設(shè)我們有兩個(gè)變量,它們需要滿足某種關(guān)系(例如,a + b = 99)。我們需要在多線程環(huán)境下保證這種關(guān)閉在任何時(shí)候都是成立的。如果這個(gè)時(shí)候我們只是將其中一個(gè)變量聲明為 volatile,雖然確保了這個(gè)變量的更新對(duì)其他線程立即可見,但卻不能保證這兩個(gè)變量作為一個(gè)整體滿足特定的不變性條件。在更新這兩個(gè)變量的過程中,其他線程可能會(huì)看到這些變量處于不一致的狀態(tài)。在這種情況下我們就需要使用鎖或者其他同步機(jī)制來保證這種關(guān)系的整體一致性。

volatile 使用場景

volatile 比較適合多個(gè)線程讀,一個(gè)線程寫的場合。

狀態(tài)標(biāo)志

當(dāng)我們需要用一個(gè)變量來作為狀態(tài)標(biāo)志,控制線程的執(zhí)行流程時(shí),使用 volatile 可以確保當(dāng)一個(gè)線程修改了這個(gè)標(biāo)志時(shí),其他線程能夠立即看到最新的值。

public class TaskRunner implements Runnable {
    private volatile boolean running = true;  // 狀態(tài)標(biāo)志,控制任務(wù)是否繼續(xù)執(zhí)行

    public void run() {
        while (running) {  // 檢查狀態(tài)標(biāo)志
            // 執(zhí)行任務(wù)
            doSomething();
        }
    }

    public void stop() {
        running = false;  // 修改狀態(tài)標(biāo)志,使得線程能夠停止執(zhí)行
    }

    private void doSomething() {
        // 實(shí)際任務(wù)邏輯
    }
}

DCL 的單例模式

在實(shí)現(xiàn)單例模式時(shí),為了保證線程安全,通常使用雙重檢查鎖定(Double-Checked Locking)模式。在這種模式中,volatile 用于避免單例實(shí)例的初始化過程中的指令重排序,確保其他線程看到一個(gè)完全初始化的單例對(duì)象,具體來說,就是使用 volatile防止了Java 對(duì)象在實(shí)例化過程中的指令重排,確保在對(duì)象的構(gòu)造函數(shù)執(zhí)行完畢之前,不會(huì)將 instance 的內(nèi)存分配操作指令重排到構(gòu)造函數(shù)之外。

public class Singleton {
    // 使用 volatile 保證實(shí)例的可見性和有序性
    private static volatile Singleton instance;

    private Singleton() {
    }
    
    public static Singleton getInstance() {
        if (instance == null) {  // 第一次檢查,避免不必要的同步
            synchronized (Singleton.class) {  // 鎖定
                if (instance == null) {  // 第二次檢查,確保只創(chuàng)建一次實(shí)例
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

開銷較低的“讀-寫鎖”策略

這種策略一般都是允許多個(gè)線程同時(shí)讀取一個(gè)資源,但只允許一個(gè)線程寫入的同步機(jī)制。這種“讀-寫鎖”非常適合讀多寫少的場景,我們可以利用 volatile + 鎖的機(jī)制減少公共代碼路徑的開銷。如下:

public class VolatileTest {  
    private volatile int value;  
    
    //讀,不加鎖,提供效率 
    public int getValue() {   
        return value;   
    }   
    //寫操作,使用鎖,保證線程安全  
    public synchronized int increment() {  
        return value++;  
    }  
}

在 J.U.C 中,有一個(gè)采用“讀-寫鎖”方式的類:ReentrantReadWriteLock,它包含兩個(gè)鎖:一個(gè)是讀鎖,另一個(gè)是寫鎖。

下面是偽代碼:

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class DataStructure {
    private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    private final Object data = ...; // 被保護(hù)的數(shù)據(jù)

    public void read() {
        readWriteLock.readLock().lock(); // 獲取讀鎖
        try {
            // 執(zhí)行讀操作
            // 例如,讀取data的內(nèi)容
        } finally {
            readWriteLock.readLock().unlock(); // 釋放讀鎖
        }
    }

    public void write(Object newData) {
        readWriteLock.writeLock().lock(); // 獲取寫鎖
        try {
            // 執(zhí)行寫操作
            // 例如,修改data的內(nèi)容
        } finally {
            readWriteLock.writeLock().unlock(); // 釋放寫鎖
        }
    }
}
  • 讀操作 :多個(gè)線程可以同時(shí)持有讀鎖,因此多個(gè)線程可以同時(shí)執(zhí)行 read() 方法。
  • 寫操作: 只有一個(gè)線程可以持有寫鎖,并且在持有寫鎖時(shí),其他線程不能讀取或?qū)懭搿?/li>

這種“讀-寫鎖”策略提高了在多線程環(huán)境下對(duì)共享資源的讀取效率,尤其是在讀操作遠(yuǎn)遠(yuǎn)多于寫操作的情況下。但是,它也會(huì)讓我們的程序變更更加復(fù)雜,比如潛在的讀寫鎖沖突、鎖升級(jí)(從讀鎖升級(jí)到寫鎖)等問題。因此,在實(shí)際應(yīng)用中,大明哥推薦直接使用 ReentrantReadWriteLock 即可,無需頭鐵自己造輪子。

以上就是Java volatile的幾種使用場景分析的詳細(xì)內(nèi)容,更多關(guān)于Java volatile使用場景的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • springboot前端傳參date類型后臺(tái)處理的方式

    springboot前端傳參date類型后臺(tái)處理的方式

    這篇文章主要介紹了springboot前端傳參date類型后臺(tái)處理的方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • 用Java驗(yàn)證pdf文件的電子章簽名

    用Java驗(yàn)證pdf文件的電子章簽名

    這篇文章主要介紹了如何用Java驗(yàn)證pdf文件的電子章簽名,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2020-12-12
  • java.util.Collections類—emptyList()方法的使用

    java.util.Collections類—emptyList()方法的使用

    這篇文章主要介紹了java.util.Collections類—emptyList()方法的使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • 做java這么久了居然還不知道JSON的使用(一文帶你了解)

    做java這么久了居然還不知道JSON的使用(一文帶你了解)

    這篇文章主要介紹了做java這么久了居然還不知道JSON的使用(一文帶你了解),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-07-07
  • springboot如何開啟緩存@EnableCaching(使用redis)

    springboot如何開啟緩存@EnableCaching(使用redis)

    在Spring Boot項(xiàng)目中集成Redis主要包括添加依賴到pom.xml、配置application.yml中的Redis連接參數(shù)、編寫配置類、在啟動(dòng)類上添加@EnableCaching注解以及測試接口的查詢和緩存驗(yàn)證等步驟,首先,需要在pom.xml中添加spring-boot-starter-data-redis依賴
    2024-11-11
  • 詳解Java如何優(yōu)雅的實(shí)現(xiàn)字典翻譯

    詳解Java如何優(yōu)雅的實(shí)現(xiàn)字典翻譯

    當(dāng)我們?cè)贘ava應(yīng)用程序中需要對(duì)字典屬性進(jìn)行轉(zhuǎn)換返回給前端時(shí),如何簡單、方便、并且優(yōu)雅的處理是一個(gè)重要問題。在本文中,我們將介紹如何使用Java中的序列化機(jī)制來優(yōu)雅地實(shí)現(xiàn)字典值的翻譯,從而簡化開發(fā)
    2023-04-04
  • 基于Java中UDP的廣播形式(實(shí)例講解)

    基于Java中UDP的廣播形式(實(shí)例講解)

    下面小編就為大家分享一篇基于Java中UDP的廣播形式(實(shí)例講解),具有很好的參考價(jià)值,希望對(duì)大家有所幫助
    2017-12-12
  • java數(shù)據(jù)結(jié)構(gòu)與算法之希爾排序詳解

    java數(shù)據(jù)結(jié)構(gòu)與算法之希爾排序詳解

    這篇文章主要介紹了java數(shù)據(jù)結(jié)構(gòu)與算法之希爾排序,結(jié)合實(shí)例形式分析了希爾排序的概念、原理、實(shí)現(xiàn)方法與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2017-05-05
  • IDEA中application.properties的圖標(biāo)顯示不正常的問題及解決方法

    IDEA中application.properties的圖標(biāo)顯示不正常的問題及解決方法

    這篇文章主要介紹了IDEA中application.properties的圖標(biāo)顯示不正常的問題及解決方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • java.text.DecimalFormat類十進(jìn)制格式化

    java.text.DecimalFormat類十進(jìn)制格式化

    這篇文章主要為大家詳細(xì)介紹了java.text.DecimalFormat類十進(jìn)制格式化的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-03-03

最新評(píng)論