搜尋

首頁  >  問答  >  主體

java关键字volatile的作用

volatile 关键字都知道是不能做到线程同步的,只能保证线程之间尽快的获取最新的值,像 concurrentHashmap 之间 value 的修饰就用到了 volatile,我感觉这个关键在没啥用的感觉,,,求解释。

或者说 volatile变量修饰符适用于什么场景?

ringa_leeringa_lee2896 天前893

全部回覆(5)我來回復

  • 迷茫

    迷茫2017-04-17 11:30:57

    關於java volatile, 我有幾點說明,

    • volatile保證可見性. 即線程得到的值是最新的. Thread1 改變了var的值, 那麼Thread2再去讀, 就是改變了的值, 而不是以前的. 再具體一點, 我的理解是這樣(有誤請指出), 現代計算機都是多核或多cpu, 一個變量可能在同一時間, 存在與不同的cpu的寄存器裡. 如果沒有volatile做保證, 那麼同一時間統一變量會有不同的值. volatile保證每次都是從主記憶體讀取/寫入變數的值, 從而保證可見性.

    • volatile保證 編譯器不會過度最佳化. 看過以下的例子, 大概的程式碼是這樣:

        public class Thread1 extends Thread {
          private boolean flag = false;
          public void run() {
            while(!flag) {
              // ...
            }
          }
          public void close() {
            flag = true;
          }
        }
    

    但是在外部程序調用close()後, Thread1並沒有退出. 用了jdk debug版本 拿到了hotspot 的匯編碼. 發現這裡while(!flag) 被編譯器優化為 while(true).

    • 對long或double來說, 讀寫不是 原子操作. 加了volatile, 對long或double的讀寫為 原子操作.

    回覆
    0
  • 怪我咯

    怪我咯2017-04-17 11:30:57

    用於修飾 多執行緒共享變數。使用此關鍵字保證jvm不會從執行緒變數中讀寫,而是直接操作共享變數

    回覆
    0
  • 迷茫

    迷茫2017-04-17 11:30:57

    我的理解是:如果有一個變量,有多個線程讀,但只有一個線程寫,那麼此變量用 volatile 可以保證讀到正確的值。 volatile 的一個經典的應用是 Double-checked locking ,它是一種在多執行緒環境下正確且有效率地實現單例模式的方法。

    參考:

    • java 多執行緒讀取一個變數要加鎖嗎

    回覆
    0
  • 高洛峰

    高洛峰2017-04-17 11:30:57

    volatile是保證被修飾變數的可見性,而不保證原子操作,經典應用是Double-checked locking。例如在多執行緒環境下修飾一個boolean變數。

    回覆
    0
  • PHP中文网

    PHP中文网2017-04-17 11:30:57

    樓主可以看下 infoq 的這篇文章:volatile

    回覆
    0
  • 取消回覆