java併發編程學習之Volatile

特性

可見性

volatile變量,是稍弱的同步機制,不會被緩存到寄存器或者其餘處理器不可見的地方,所以讀取時,總會返回當前的最新值。這個性質,就是可見性,是Volatile的關鍵做用之一。可是Volatile的語義不足以確保遞增操做的原子性,在多線程的狀況下,線程不必定是安全的。緩存

禁止重排序

由於編譯器優化、指令重排序、內存系統重排序緣由,程序執行的順序,不必定等於咱們編寫的順序,Volatile會禁止重排序。安全

經常使用場景:

禁止重排序

單例模式(懶漢模式)
clipboard.png
咱們模擬兩個線程A,B,在還沒建立單例對象的時候,一塊兒進入getInstance方法。多線程

  • A進入16行,此時singleton爲空,時間片結束。
  • B也進入16行,獲取到的singleton也是空,時間片結束。
  • A進入17行,這邊是對象鎖,,B在等待A執行完這個代碼塊。
  • A執行完,生成singleton對象,因爲重排序,singleton對象的其餘域可能還沒初始化。
  • B繼續執行,此時獲取singleton,可是其餘域可能還沒初始化,調用時,報空指針異常。

可見性

檢查某個狀態標記,以判斷是否退出循環優化

Volatile boolean done;
....
某個方法{
    while(done){
       doSomeThing1();
    }
    doSomeThing2();
}

這邊和用普通的變量的區別是,在多線程的狀況下,取到done後,done的值被改變了,while判斷會不正確。spa

使用的條件

  1. 對變量的寫入操做,不依賴變量的當前值,或者確保單線程更新變量的值
  2. 該變量不會和其餘變量一塊兒歸入不變形條件中
  3. 訪問變量時,不須要加鎖
相關文章
相關標籤/搜索