国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

JUC并發(fā)編程之volatile詳解

這篇具有很好參考價(jià)值的文章主要介紹了JUC并發(fā)編程之volatile詳解。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

目錄

?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-624108.html

1. volatile

1.1?volatile關(guān)鍵字的作用

1.1.1?變量可見(jiàn)性

1.1.2?禁止指令重排序

1.2 volatile可見(jiàn)性案例

1.3 volatile非原子性案例

1.4 volatile 禁止重排序

1.5 volatile 日常使用場(chǎng)景

送書(shū)活動(dòng)


?

1. volatile

在并發(fā)編程中,多線程操作共享的變量時(shí),可能會(huì)導(dǎo)致線程安全問(wèn)題,如數(shù)據(jù)競(jìng)爭(zhēng)、可見(jiàn)性問(wèn)題等。為了解決這些問(wèn)題,Java提供了JUC(java.util.concurrent)工具包,其中包含了很多用于處理并發(fā)編程的工具類(lèi)和接口。在JUC中,volatile是一個(gè)關(guān)鍵字,它可以用于修飾變量,用來(lái)確保變量的可見(jiàn)性和禁止指令重排序,從而在一定程度上解決線程安全問(wèn)題。

1.1?volatile關(guān)鍵字的作用

1.1.1?變量可見(jiàn)性

在多線程環(huán)境下,如果一個(gè)線程修改了共享變量的值,其他線程可能由于線程間的數(shù)據(jù)不一致性而看不到該變量的最新值。這種問(wèn)題稱(chēng)為“變量不可見(jiàn)性”或“可見(jiàn)性問(wèn)題”。

volatile關(guān)鍵字可以確保被修飾的變量對(duì)所有線程可見(jiàn)。當(dāng)一個(gè)線程修改了volatile變量的值,其他線程立即能夠看到修改后的最新值,而不會(huì)使用緩存中的舊值。

1.1.2?禁止指令重排序

在JVM(Java虛擬機(jī))中,為了優(yōu)化性能,編譯器和處理器可能會(huì)對(duì)指令進(jìn)行重排序。在單線程環(huán)境下,這種重排序不會(huì)影響程序的執(zhí)行結(jié)果。然而,在多線程環(huán)境下,指令重排序可能會(huì)導(dǎo)致線程安全問(wèn)題。

volatile關(guān)鍵字可以防止指令重排序,確保被修飾的變量按照代碼中的順序執(zhí)行。

1.2 volatile可見(jiàn)性案例

public class VolatileExample {
    private static volatile boolean flag = false;

    public static void main(String[] args) {
        new Thread(() -> {
            while (!flag) {
                System.out.println("Waiting for the flag to be true...");
            }
            System.out.println("Flag is now true. Exiting the thread.");
        }).start();

        try {
            Thread.sleep(1000); // 確保主線程在子線程之前執(zhí)行
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("Setting the flag to true...");
        flag = true;
    }
}

在上面的示例中,我們創(chuàng)建了一個(gè)VolatileExample類(lèi),并聲明了一個(gè)volatile類(lèi)型的flag變量。在主線程中,我們啟動(dòng)一個(gè)新的子線程,該子線程會(huì)不斷地檢查flag變量的值,直到flag變?yōu)?code>true時(shí),子線程退出。

在主線程中,我們將flag變量設(shè)置為true。由于flag變量被聲明為volatile類(lèi)型,子線程能夠及時(shí)看到flag的最新值,從而退出循環(huán),輸出“Flag is now true. Exiting the thread.”。

這個(gè)示例演示了volatile關(guān)鍵字的作用,確保了flag變量的可見(jiàn)性。如果我們沒(méi)有使用volatile關(guān)鍵字,子線程可能會(huì)一直循環(huán)下去,因?yàn)樗床坏街骶€程對(duì)flag的修改。

JUC并發(fā)編程之volatile詳解,并發(fā)編程和高并發(fā)實(shí)戰(zhàn),java,jvm,開(kāi)發(fā)語(yǔ)言

?

1.3 volatile非原子性案例

public class Test {


    public static void main(String[] args) throws InterruptedException {
        VolatileAtomicityExample example = new VolatileAtomicityExample();
        for(int i=1;i<=100;i++){
            new Thread(()->{
                for(int j=1;j<=1000;j++)
                    example.increment();
            },String.valueOf(i)).start();
        }
        TimeUnit.SECONDS.sleep(2);
        System.out.println(example.getCount());


    }

}
class VolatileAtomicityExample {
    volatile int count = 0;

    public  void increment() {
        count++;
    }

    public int getCount() {
        return count;
    }
}

我們創(chuàng)建了一個(gè)VolatileAtomicityExample類(lèi),其中的成員變量count被聲明為volatile類(lèi)型。然后,我們創(chuàng)建了100個(gè)線程,每個(gè)線程分別執(zhí)行1000次increment()操作,對(duì)count進(jìn)行自增。最后,我們?cè)谥骶€程中打印count的最終值。以上示例中的輸出結(jié)果可能會(huì)因?yàn)檫\(yùn)行時(shí)的不確定性而有所不同。每次運(yùn)行時(shí)可能得到不同的結(jié)果,但通常結(jié)果都小于100000。為了解決這個(gè)問(wèn)題,我們需要使用synchronized關(guān)鍵字或其他線程安全機(jī)制來(lái)確保increment()方法的原子性。

這是什么原因呢?

JUC并發(fā)編程之volatile詳解,并發(fā)編程和高并發(fā)實(shí)戰(zhàn),java,jvm,開(kāi)發(fā)語(yǔ)言

?對(duì)于volatile變量具備可見(jiàn)性,JVM只是保證從主內(nèi)存加載到線程工作內(nèi)存的值是最新的,也僅是數(shù)據(jù)加載時(shí)是最新的。但是多線程環(huán)境下,"數(shù)據(jù)計(jì)算"和"數(shù)據(jù)賦值"操作可能多次出現(xiàn),若數(shù)據(jù)在加載之后,若主內(nèi)存volatile修飾變量發(fā)生修改之后,線程工作內(nèi)存中的操作將會(huì)作廢去讀主內(nèi)存最新值,操作出現(xiàn)寫(xiě)丟失問(wèn)題。即各線程私有內(nèi)存和主內(nèi)存公共內(nèi)存中變量不同步,進(jìn)而導(dǎo)致數(shù)據(jù)不一致。由此可見(jiàn)volatile解決的是變量讀時(shí)的可見(jiàn)性問(wèn)題,但無(wú)法保證原子性,對(duì)于多線程修改主內(nèi)存共享變量的場(chǎng)景必須使用加鎖同步。

1.4 volatile 禁止重排序

內(nèi)存屏障是一種硬件指令或者編譯器指令,用于控制內(nèi)存操作的順序,以確保多線程環(huán)境下的內(nèi)存可見(jiàn)性和正確的執(zhí)行順序。

內(nèi)存屏障分為兩種類(lèi)型:

  1. 內(nèi)存讀屏障(Load Barrier):它是一個(gè)特殊的硬件或者編譯器指令,用于保證在內(nèi)存讀取操作之前,所有的先行寫(xiě)操作都已經(jīng)完成,并且其結(jié)果對(duì)當(dāng)前線程可見(jiàn)。也就是說(shuō),讀屏障可以防止后續(xù)讀取指令重排序到讀屏障之前的位置。

  2. 內(nèi)存寫(xiě)屏障(Store Barrier):它是一個(gè)特殊的硬件或者編譯器指令,用于保證在內(nèi)存寫(xiě)入操作之前,所有的先行寫(xiě)操作和寫(xiě)屏障之前的寫(xiě)操作都已經(jīng)完成,并且其結(jié)果對(duì)其他線程可見(jiàn)。也就是說(shuō),寫(xiě)屏障可以防止前面的寫(xiě)入指令重排序到寫(xiě)屏障之后的位置。

volatile關(guān)鍵字通過(guò)內(nèi)存屏障來(lái)保證變量的讀寫(xiě)操作不會(huì)被重排序。具體來(lái)說(shuō),對(duì)于volatile變量的寫(xiě)操作,在寫(xiě)入變量之后會(huì)插入寫(xiě)屏障,這樣可以防止其他指令重排序到寫(xiě)屏障之前。類(lèi)似地,對(duì)于volatile變量的讀操作,在讀取變量之前會(huì)插入讀屏障,這樣可以防止其他指令重排序到讀屏障之前。

通過(guò)這種方式,volatile關(guān)鍵字確保了對(duì)變量的讀寫(xiě)操作具有一定的有序性,從而保證了多線程環(huán)境下的內(nèi)存可見(jiàn)性和正確的執(zhí)行順序。

1.5 volatile 日常使用場(chǎng)景

狀態(tài)標(biāo)志:當(dāng)一個(gè)線程修改了某個(gè)狀態(tài)標(biāo)志,其他線程需要立即看到最新的狀態(tài)。這時(shí)可以使用volatile關(guān)鍵字修飾狀態(tài)標(biāo)志,保證其在多線程之間的可見(jiàn)性。例如:

public class Task implements Runnable {
    private volatile boolean isRunning = true;

    @Override
    public void run() {
        while (isRunning) {
            // 執(zhí)行任務(wù)邏輯
        }
    }

    public void stop() {
        isRunning = false;
    }
}

雙重檢查鎖定(Double-Checked Locking):在多線程環(huán)境下,當(dāng)需要延遲初始化一個(gè)對(duì)象時(shí),為了避免重復(fù)初始化,常常使用雙重檢查鎖定。在這種情況下,需要使用volatile關(guān)鍵字來(lái)確保對(duì)象在多線程環(huán)境中的可見(jiàn)性。例如:

public class Singleton {
    private volatile static Singleton instance;

    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

在上述代碼中,我們實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的單例模式。在getInstance()方法中,我們使用雙重檢查鎖定來(lái)實(shí)現(xiàn)延遲初始化,確保只有在instance為空時(shí)才創(chuàng)建新的Singleton實(shí)例。

然而,在多線程環(huán)境下,由于指令重排序的存在,可能會(huì)導(dǎo)致以下問(wèn)題:

  1. 對(duì)象引用不為空但尚未初始化:在線程A執(zhí)行完instance = new Singleton();這一行之前,可能發(fā)生指令重排序,導(dǎo)致instance的引用不為空,但是Singleton實(shí)例的初始化還未完成。這樣,線程B在執(zhí)行return instance;時(shí)就會(huì)得到一個(gè)尚未初始化的對(duì)象,導(dǎo)致錯(cuò)誤。

  2. 可見(jiàn)性問(wèn)題:指令重排序也可能導(dǎo)致線程B無(wú)法及時(shí)看到線程A的初始化操作。例如,線程A對(duì)instance的賦值可能被重排到線程A的后面執(zhí)行,從而線程B在讀取instance時(shí)得到一個(gè)舊的引用,無(wú)法感知線程A的初始化操作。

為了解決這個(gè)問(wèn)題,需要在創(chuàng)建Singleton實(shí)例時(shí)使用volatile關(guān)鍵字來(lái)保證對(duì)象的可見(jiàn)性和禁止指令重排序。

?

送書(shū)活動(dòng)

《硅基物語(yǔ)·我是靈魂畫(huà)手》

?

當(dāng)AI遇上繪畫(huà),會(huì)打開(kāi)怎樣的奇妙世界?

用ChatGPT+Midjourney西出人類(lèi)的靈魂與夢(mèng)想

用StableDiffusion+D-ID畫(huà)出青春絢麗的渴望

激活每個(gè)人隱藏的繪畫(huà)天賦

人人都能成為頂尖繪畫(huà)大師

?

ChatGPT+Midjourncy+StableDiffusion+D-ID+RunwayGen-l

爆火軟件全流程協(xié)作

掌據(jù)AI繪商技巧

解鎖超全繪畫(huà)關(guān)鍵司

講解創(chuàng)作底層邏輯

一本書(shū)講透AI繪畫(huà)全流程

?

內(nèi)容簡(jiǎn)介

一本將AI繪畫(huà)講透的探秘指南,通過(guò)豐富的實(shí)踐案例操作,通俗易懂地講述AI繪畫(huà)的生成步驟生動(dòng)展現(xiàn)了AI繪畫(huà)的魔法魅力。從歷史到未來(lái),跨越百年時(shí)空,從理論到實(shí)踐,講述案例操作:從技術(shù)到哲學(xué),穿越多個(gè)維度,從語(yǔ)言到繪畫(huà),落地實(shí)戰(zhàn)演練。AI繪畫(huà)的誕生,引發(fā)了奇點(diǎn)降臨,點(diǎn)亮了AGI(通用人工智能),并涉及 Prompt、風(fēng)格,技術(shù)細(xì)節(jié)、多模態(tài)交互,AIGC等一系列詳細(xì)講解。讓您輕松掌握生圖技巧,創(chuàng)造出獨(dú)特的藝術(shù)作品,書(shū)寫(xiě)屬于自己的藝術(shù)時(shí)代。

?

JUC并發(fā)編程之volatile詳解,并發(fā)編程和高并發(fā)實(shí)戰(zhàn),java,jvm,開(kāi)發(fā)語(yǔ)言

?當(dāng)當(dāng)網(wǎng)鏈接:http://product.dangdang.com/29601870.html

?

?關(guān)注博主、點(diǎn)贊、收藏、

評(píng)論區(qū)評(píng)論

??即可參與送書(shū)活動(dòng)!?

?

到了這里,關(guān)于JUC并發(fā)編程之volatile詳解的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • java JUC并發(fā)編程 第六章 CAS

    java JUC并發(fā)編程 第六章 CAS

    第一章 java JUC并發(fā)編程 Future: link 第二章 java JUC并發(fā)編程 多線程鎖: link 第三章 java JUC并發(fā)編程 中斷機(jī)制: link 第四章 java JUC并發(fā)編程 java內(nèi)存模型JMM: link 第五章 java JUC并發(fā)編程 volatile與JMM: link 第六章 java JUC并發(fā)編程 CAS: link 第七章 java JUC并發(fā)編程 原子操作類(lèi)增強(qiáng): link 第八章

    2024年02月10日
    瀏覽(23)
  • java JUC并發(fā)編程 第九章 對(duì)象內(nèi)存布局與對(duì)象頭

    java JUC并發(fā)編程 第九章 對(duì)象內(nèi)存布局與對(duì)象頭

    第一章 java JUC并發(fā)編程 Future: link 第二章 java JUC并發(fā)編程 多線程鎖: link 第三章 java JUC并發(fā)編程 中斷機(jī)制: link 第四章 java JUC并發(fā)編程 java內(nèi)存模型JMM: link 第五章 java JUC并發(fā)編程 volatile與JMM: link 第六章 java JUC并發(fā)編程 CAS: link 第七章 java JUC并發(fā)編程 原子操作類(lèi)增強(qiáng): link 第八章

    2024年02月07日
    瀏覽(18)
  • 【并發(fā)編程】JUC并發(fā)編程(徹底搞懂JUC)

    【并發(fā)編程】JUC并發(fā)編程(徹底搞懂JUC)

    如果你對(duì)多線程沒(méi)什么了解,那么從入門(mén)模塊開(kāi)始。 如果你已經(jīng)入門(mén)了多線程(知道基礎(chǔ)的線程創(chuàng)建、死鎖、synchronized、lock等),那么從juc模塊開(kāi)始。 新手學(xué)技術(shù)、老手學(xué)體系,高手學(xué)格局。 JUC實(shí)際上就是我們對(duì)于jdk中java.util .concurrent 工具包的簡(jiǎn)稱(chēng) ,其結(jié)構(gòu)如下: 這個(gè)包

    2024年02月20日
    瀏覽(19)
  • 并發(fā)編程-JUC-原子類(lèi)

    并發(fā)編程-JUC-原子類(lèi)

    JUC 整體概覽 原子類(lèi) 基本類(lèi)型-使用原子的方式更新基本類(lèi)型 AtomicInteger:整形原子類(lèi) AtomicLong:長(zhǎng)整型原子類(lèi) AtomicBoolean :布爾型原子類(lèi) 引用類(lèi)型 AtomicReference:引用類(lèi)型原子類(lèi) AtomicStampedReference:原子更新引用類(lèi)型里的字段原子類(lèi) AtomicMarkableReference :原子更新帶有標(biāo)記位的引

    2024年02月21日
    瀏覽(23)
  • JUC并發(fā)編程(二)

    JUC并發(fā)編程(二)

    JUC并發(fā)編程(續(xù)) 接上一篇筆記:https://blog.csdn.net/weixin_44780078/article/details/130694996 五、Java內(nèi)存模型 JMM 即 Java Memory Model,它定義了主存、工作內(nèi)存抽象概念,底層對(duì)應(yīng)著CPU寄存器、緩存、硬件內(nèi)存、CPU 指令優(yōu)化等。 JMM 體現(xiàn)在以下幾個(gè)方面: 原子性:保證指令不會(huì)受到線程

    2024年02月05日
    瀏覽(27)
  • 第九章 JUC并發(fā)編程

    第九章 JUC并發(fā)編程

    http://t.csdn.cn/UgzQi 使用 AQS加 Lock 接口實(shí)現(xiàn)簡(jiǎn)單的不可重入鎖 早期程序員會(huì)自己通過(guò)一種同步器去實(shí)現(xiàn)另一種相近的同步器,例如用可重入鎖去實(shí)現(xiàn)信號(hào)量,或反之。這顯然不夠優(yōu)雅,于是在 JSR166(java 規(guī)范提案)中創(chuàng)建了 AQS,提供了這種通用的同步器機(jī)制。 AQS 要實(shí)現(xiàn)的功能

    2023年04月08日
    瀏覽(21)
  • 【JUC并發(fā)編程】

    【JUC并發(fā)編程】

    本筆記內(nèi)容為狂神說(shuō)JUC并發(fā)編程部分 目錄 一、什么是JUC 二、線程和進(jìn)程 1、概述? 2、并發(fā)、并行 3、線程有幾個(gè)狀態(tài)? 4、wait/sleep 區(qū)別 三、Lock鎖(重點(diǎn))? 四、生產(chǎn)者和消費(fèi)者問(wèn)題 五、八鎖現(xiàn)象 六、集合類(lèi)不安全? 七、Callable ( 簡(jiǎn)單 ) 八、常用的輔助類(lèi)(必會(huì)) 1、CountDown

    2024年02月09日
    瀏覽(11)
  • JUC并發(fā)編程14 | ThreadLocal

    JUC并發(fā)編程14 | ThreadLocal

    尚硅谷JUC并發(fā)編程(100-111) ThreadLocal是什么? ThreadLocal 提供 線程局部變量 。這些變量與正常的變量有所不同,因?yàn)槊恳粋€(gè)線程在訪問(wèn)ThreadLocal實(shí)例的時(shí)候(通過(guò)其get或set方法)都有自己的、獨(dú)立初始化的變量副本。ThreadLocal實(shí)例通常是類(lèi)中的私有靜態(tài)字段,使用它的目的是

    2024年02月04日
    瀏覽(23)
  • JUC 高并發(fā)編程基礎(chǔ)篇

    JUC 高并發(fā)編程基礎(chǔ)篇

    ? 1、什么是 JUC ? 2、Lock 接口 ? 3、線程間通信 ? 4、集合的線程安全 ? 5、多線程鎖 ? 6、Callable 接口 ? 7、JUC 三大輔助類(lèi): CountDownLatch CyclicBarrier Semaphore ? 8、讀寫(xiě)鎖: ReentrantReadWriteLock ? 9、阻塞隊(duì)列 ? 10、ThreadPool 線程池 ? 11、Fork/Join 框架 ? 12、CompletableFuture 1 什么

    2024年02月07日
    瀏覽(20)
  • JUC并發(fā)編程之原子類(lèi)

    目錄 1. 什么是原子操作 1.1?原子類(lèi)的作用 1.2?原子類(lèi)的常見(jiàn)操作 原子類(lèi)的使用注意事項(xiàng) 并發(fā)編程是現(xiàn)代計(jì)算機(jī)應(yīng)用中不可或缺的一部分,而在并發(fā)編程中,處理共享資源的并發(fā)訪問(wèn)是一個(gè)重要的問(wèn)題。為了避免多線程訪問(wèn)共享資源時(shí)出現(xiàn)競(jìng)態(tài)條件(Race Condition)等問(wèn)題,J

    2024年02月13日
    瀏覽(18)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包