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

Java的Volatile實(shí)例用法及講解

 更新時(shí)間:2019年09月01日 14:14:44   作者:konami  
在本篇文章里小編給大家整理了關(guān)于Java的Volatile知識(shí)點(diǎn)相關(guān)內(nèi)容,有需要的朋友們可以跟著學(xué)習(xí)下。

在原子性、可見(jiàn)性、有序性中,volatile關(guān)鍵字主要在可見(jiàn)性中發(fā)揮作用。

volatile聲明的變量對(duì)所有線程來(lái)說(shuō)是可見(jiàn)的,就是說(shuō)當(dāng)變量的值發(fā)生改變的時(shí)候,其他線程可以立馬發(fā)現(xiàn)這個(gè)變化。

public class Main {
  private static boolean isRuning;
  private static int number;

  private static class ReaderThread extends Thread {
    public void run() {
      while (!isRuning) {
        System.out.println(number);
      }
    }
  }

  public static void main(String[] args) throws InterruptedException {
    new ReaderThread().start();
    Thread.sleep(1000);
    number = 42;
    isRuning = true;
    Thread.sleep(1000);
  }
}

應(yīng)該是由于編譯器優(yōu)化的存在,這里變量雖然沒(méi)有被volatile修飾,但是仍然對(duì)其他線程可見(jiàn)。。。。。

那為啥Volatile修飾的變量i++卻會(huì)有并發(fā)問(wèn)題呢?

因?yàn)閕++并不是原子操作,

i++是有兩步操作的,比如 i=0; i++

1.讀取i=0

2.計(jì)算i+1,然后賦值給i

那么可能存在2個(gè)線程同時(shí)讀取到i=0,并計(jì)算出結(jié)果i=1然后賦值給I

那么就得不到預(yù)期結(jié)果i=2。

就是說(shuō)雖然Volatile修飾的變量的變化可以被其他線程看到,但是如果同時(shí)去讀這個(gè)變量,然后進(jìn)行寫(xiě)操作,則仍會(huì)導(dǎo)致線程安全問(wèn)題。

更底層的原因是什么呢?

首先要知道Volatile修飾的變量會(huì)做兩件事(由lock指令完成):

  • 1)將當(dāng)前處理器緩存行的數(shù)據(jù)寫(xiě)回到系統(tǒng)內(nèi)存。
  • 2)寫(xiě)回內(nèi)存的操作會(huì)使在其他 CPU 里緩存了該內(nèi)存地址的額數(shù)據(jù)無(wú)效。

其他緩存會(huì)失效,不正好可以保證Volatile的原子性嗎?

然而并不是,

比如有T1 T2兩個(gè)線程進(jìn)行i++操作。

當(dāng)T1將變量加載到緩存,但是還沒(méi)進(jìn)行i++運(yùn)算,T2呢已經(jīng)加載完緩存并且已經(jīng)執(zhí)行完運(yùn)算,那這個(gè)時(shí)候T1緩存里的值就該變成無(wú)效的了。

但是Volatile并不是讓其他線程緩存無(wú)效以后就去重新加載主內(nèi)存中的值,如果這時(shí)候T2緩存的值已經(jīng)被放到寄存器并且cpu進(jìn)行計(jì)算了,那即使緩存無(wú)效也不會(huì)影響T2將計(jì)算的值回寫(xiě)到主內(nèi)存中。

關(guān)于cpu執(zhí)行指令的過(guò)程可以參考https://blog.csdn.net/jizhu4873/article/details/84393905

當(dāng)一個(gè)變量定義為 volatile 之后,將具備兩種特性:

1.保證此變量對(duì)所有的線程的可見(jiàn)性,這里的“可見(jiàn)性”,如本文開(kāi)頭所述,當(dāng)一個(gè)線程修改了這個(gè)變量的值,volatile 保證了新值能立即同步到主內(nèi)存,以及每次使用前立即從主內(nèi)存刷新。但普通變量做不到這點(diǎn),普通變量的值在線程間傳遞均需要通過(guò)主內(nèi)存(詳見(jiàn):Java內(nèi)存模型)來(lái)完成。

2.禁止指令重排序優(yōu)化。有volatile修飾的變量,賦值后多執(zhí)行了一個(gè)“l(fā)oad addl $0x0, (%esp)”操作,這個(gè)操作相當(dāng)于一個(gè)內(nèi)存屏障(指令重排序時(shí)不能把后面的指令重排序到內(nèi)存屏障之前的位置),只有一個(gè)CPU訪問(wèn)內(nèi)存時(shí),并不需要內(nèi)存屏障;(什么是指令重排序:是指CPU采用了允許將多條指令不按程序規(guī)定的順序分開(kāi)發(fā)送給各相應(yīng)電路單元處理)。

volatile 變量的內(nèi)存可見(jiàn)性是基于內(nèi)存屏障(Memory Barrier)實(shí)現(xiàn)。

內(nèi)存屏障則由lock指令實(shí)現(xiàn)

以上就是本次介紹的全部知識(shí)點(diǎn)內(nèi)容,感謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • javax.servlet不存在的解決辦法

    javax.servlet不存在的解決辦法

    今天在關(guān)于servlet的編譯中出現(xiàn)了一下小小的錯(cuò)誤,發(fā)現(xiàn)javax.servlet不存在,本文就介紹一下解決方法,感興趣的可以了解一下
    2021-07-07
  • Java實(shí)現(xiàn)簡(jiǎn)易俄羅斯方塊

    Java實(shí)現(xiàn)簡(jiǎn)易俄羅斯方塊

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)簡(jiǎn)易俄羅斯方塊,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-06-06
  • SpringBoot接口調(diào)用之后報(bào)404問(wèn)題的解決方案

    SpringBoot接口調(diào)用之后報(bào)404問(wèn)題的解決方案

    這篇文章主要介紹了SpringBoot接口調(diào)用之后報(bào)404問(wèn)題的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。
    2021-06-06
  • idea切換git地址并刷新右下角git分支

    idea切換git地址并刷新右下角git分支

    這篇文章主要介紹了idea切換git地址并刷新右下角git分支,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • Java超詳細(xì)講解繼承和多態(tài)的使用

    Java超詳細(xì)講解繼承和多態(tài)的使用

    繼承就是可以直接使用前輩的屬性和方法。自然界如果沒(méi)有繼承,那一切都是處于混沌狀態(tài)。多態(tài)是同一個(gè)行為具有多個(gè)不同表現(xiàn)形式或形態(tài)的能力。多態(tài)就是同一個(gè)接口,使用不同的實(shí)例而執(zhí)行不同操作
    2022-05-05
  • mybatis if標(biāo)簽判斷不生效的解決方法

    mybatis if標(biāo)簽判斷不生效的解決方法

    這篇文章主要介紹了mybatis if標(biāo)簽判斷不生效的解決方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • 一定要讓你搞懂Java位運(yùn)算符

    一定要讓你搞懂Java位運(yùn)算符

    這篇文章主要為大家介紹了Java位運(yùn)算符,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-01-01
  • Java中Prime算法的原理與實(shí)現(xiàn)詳解

    Java中Prime算法的原理與實(shí)現(xiàn)詳解

    Prime算法是一種窮舉查找算法來(lái)從一個(gè)連通圖中構(gòu)造一棵最小生成樹(shù)。本文主要為大家介紹了Java中Prime算法的原理與實(shí)現(xiàn),感興趣的可以學(xué)習(xí)一下
    2022-07-07
  • PowerJob的CleanService清理服務(wù)流程

    PowerJob的CleanService清理服務(wù)流程

    這篇文章主要為大家介紹了PowerJob的CleanService清理服務(wù)流程源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪<BR>
    2024-02-02
  • Java中DecimalFormat用法詳解

    Java中DecimalFormat用法詳解

    這篇文章主要為大家詳細(xì)介紹了Java中DecimalFormat的用法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-03-03

最新評(píng)論

肥乡县| 弥勒县| 亳州市| 木兰县| 刚察县| 天峨县| 大方县| 广丰县| 百色市| 庆云县| 维西| 苍梧县| 双牌县| 金川县| 石阡县| 衡阳县| 安溪县| 安义县| 从化市| 靖江市| 嵊州市| 石泉县| 平利县| 澄江县| 盈江县| 合阳县| 广东省| 安新县| 温泉县| 平利县| 万年县| 凌源市| 龙州县| 石嘴山市| 务川| 南部县| 鄂尔多斯市| 陆丰市| 霍山县| 富顺县| 诏安县|