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

Java的Volatile實例用法及講解

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

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

volatile聲明的變量對所有線程來說是可見的,就是說當變量的值發(fā)生改變的時候,其他線程可以立馬發(fā)現(xiàn)這個變化。

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ōu)化的存在,這里變量雖然沒有被volatile修飾,但是仍然對其他線程可見。。。。。

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

因為i++并不是原子操作,

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

1.讀取i=0

2.計算i+1,然后賦值給i

那么可能存在2個線程同時讀取到i=0,并計算出結果i=1然后賦值給I

那么就得不到預期結果i=2。

就是說雖然Volatile修飾的變量的變化可以被其他線程看到,但是如果同時去讀這個變量,然后進行寫操作,則仍會導致線程安全問題。

更底層的原因是什么呢?

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

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

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

然而并不是,

比如有T1 T2兩個線程進行i++操作。

當T1將變量加載到緩存,但是還沒進行i++運算,T2呢已經(jīng)加載完緩存并且已經(jīng)執(zhí)行完運算,那這個時候T1緩存里的值就該變成無效的了。

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

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

當一個變量定義為 volatile 之后,將具備兩種特性:

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

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

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

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

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

相關文章

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

    javax.servlet不存在的解決辦法

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

    Java實現(xiàn)簡易俄羅斯方塊

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

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

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

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

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

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

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

    mybatis if標簽判斷不生效的解決方法

    這篇文章主要介紹了mybatis if標簽判斷不生效的解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-02-02
  • 一定要讓你搞懂Java位運算符

    一定要讓你搞懂Java位運算符

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

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

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

    PowerJob的CleanService清理服務流程

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

    Java中DecimalFormat用法詳解

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

最新評論

九寨沟县| 嘉兴市| 日喀则市| 霞浦县| 霍州市| 安溪县| 上林县| 龙泉市| 松潘县| 玉田县| 台江县| 和林格尔县| 重庆市| 许昌市| 荥经县| 左贡县| 大港区| 津南区| 富源县| 台湾省| 洮南市| 盐城市| 莱芜市| 宁陵县| 长沙县| 漯河市| 淳化县| 长武县| 桦川县| 兴隆县| 淄博市| 灌云县| 新河县| 巩留县| 重庆市| SHOW| 乡宁县| 泌阳县| 蓬莱市| 德惠市| 石林|