亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java多線程并發編程 Volatile關鍵字

發布時間:2020-08-26 13:18:04 來源:腳本之家 閱讀:114 作者:mdxy-dxy 欄目:編程語言

volatile 關鍵字是一個神秘的關鍵字,也許在 J2EE 上的 JAVA 程序員會了解多一點,但在 Android 上的 JAVA 程序員大多不了解這個關鍵字。只要稍了解不當就好容易導致一些并發上的錯誤發生,例如好多人把 volatile 理解成變量的鎖。(并不是)

volatile 的特性:

具備可見性

保證不同線程對被 volatile 修飾的變量的可見性。

有一被 volatile 修飾的變量 i,在一個線程中修改了此變量 i,對于其他線程來說 i 的修改是立即可見的。

如:

volatile int i = 0;// 語句 1
i++; // 語句 2

語句 2 執行完后,i 最新的值會立即被強制更新到主內存(共享內存),并通知其他緩存了 i 的線程,令其他線程的工作內存里的 i 失效,從而需重新到主內存讀取最新的值。

具備有序性

被 volatile 修飾的變量,不會被優化排序。

解決的問題詳見:Java 多線程并發編程 并發三大要素 的 三、有序性。

當編譯器在給程序優化排序時,若遇到 volatile 變量的讀操作或者寫操作,則會保證在其前面的操作全部進行完成,且結果對后面的操作可見;并且保證在其后面的操作沒有進行。

不具備原子性

volatile 不具備原子性,所以它是線程不安全的。

實驗:

// 一個單例的實現
public class SingletonTest {

  private static volatile SingletonTest mInstance = null;

  private SingletonTest() {}

  public static SingletonTest getInstance() {

    if (mInstance == null) {
      mInstance = new SingletonTest();
      System.out.println(" 初始化完成 ");
    }

    return mInstance;
  }
}


// 測試代碼
public class Test {

  public static void main(String[] var0) {
    for(int i = 0; i < 20; i++){
      ThreadTest test = new ThreadTest();
      test.start();
    }
  }

  static class ThreadTest extends Thread{

    @Override
    public void run() {
      super.run();

      SingletonTest.getInstance();
    }
  }

}

結果:
每次運行都輸出多個 “初始化完成”。

volatile 的解釋

下面這段話摘自《深入理解 Java 虛擬機》:

“觀察加入 volatile 關鍵字和沒有加入 volatile 關鍵字時所生成的匯編代碼發現,加入 volatile 關鍵字時,會多出一個 lock 前綴指令”

被 volatile 修飾的變量進行讀和寫操作的時候,在相應的匯編程序中都會多一句內存屏障(Memory Barrier)。

而這個 lock 就是內存屏障。

內存屏障的作用:

1、在重新優化排序時保證其后面的指令不會被排到內存屏障的前面,前面的指令也不會排到內存屏障的后面。- 有序性

2、強制對寫操作后的結果(立即)刷新到主內存。

3、刷新結果到主內存時,通知并令其他線程緩存內的值過期 / 失效。

2 和 3 合起來則是可見性。

說到這里,也許會有好多人困惑,既然可見性可以保證,既然可以做到修改某個變量的值后,會刷新到主內存,并令其他線程緩存失效,為什么不能保證原子性呢?這也是我之前走進的一個困區。

繼續用 i++ 來分析一下,這里面包含的指令:

從主內存讀取到緩存 // 指令 1
進行運算 // 指令 2
從緩存刷新到主內存 // 指令 3
內存屏障 // 指令 4

雖然指令 4(內存屏障)功能強大,但可惜 // 指令 1、2、3 都不是具備原子性,所以導致 volatile 不具備原子性,線程不安全,不能替代鎖的作用。

使用場景

如一些簡單的狀態標記:

volatile boolean inited = false;

// 線程 1
init(); // 語句 1
inited = true; // 語句 2

// 線程 2
while(inited){
	work(); // 語句 3
}

1、可確保語句 1 和語句 2 的執行順序。
2、可確保執行語句 2 后,線程 2 可立即獲取到最新的修改,從而執行語句 3。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

横峰县| 闵行区| 开封市| 宁乡县| 浪卡子县| 米泉市| 八宿县| 太康县| 榆社县| 洞口县| 伊宁县| 齐齐哈尔市| 怀远县| 临海市| 南江县| 鄂伦春自治旗| 山东省| 日照市| 仁化县| 柳州市| 理塘县| 合川市| 华池县| 内江市| 广宁县| 安丘市| 襄城县| 阳信县| 萝北县| 伊吾县| 广饶县| 万荣县| 临夏县| 鄢陵县| 峨边| 内黄县| 庆元县| 仲巴县| 新安县| 新河县| 上犹县|