synchronized&volatile

在java線程併發處理中,有一個關鍵字volatile的使用目前存在很大的混淆,覺得使用這個關鍵字,在進行多線程併發處理的時候就能夠萬事大吉。java

Java語言是支持多線程的,爲了解決線程併發的問題,在語言內部引入了 同步塊 和 volatile 關鍵字機制。編程

 


synchronized 安全

同步塊你們都比較熟悉,經過 synchronized 關鍵字來實現,全部加上synchronized 和 塊語句,在多線程訪問的時候,同一時刻只能有一個線程可以用多線程

synchronized 修飾的方法 或者 代碼塊。併發

 


volatilejvm

用volatile修飾的變量,線程在每次使用變量的時候,都會讀取變量修改後的最的值。volatile很容易被誤用,用來進行原子性操做。優化

要使 volatile 變量提供理想的線程安全,必須同時知足下面兩個條件:spa

  • 對變量的寫操做不依賴於當前值。
  • 該變量沒有包含在具備其餘變量的不變式中。

實際上,這些條件代表,能夠被寫入 volatile 變量的這些有效值獨立於任何程序的狀態,包括變量的當前狀態。 線程

第一個條件的限制使 volatile 變量不能用做線程安全計數器。雖然增量操做(x++)看上去相似一個單獨操做,實際上它是一個由讀取-修改-寫入操做序列組成的組合操做,必須以原子方式執行,而 volatile 不能提供必須的原子特性。實現正確的操做須要使 x 的值在操做期間保持不變,而 volatile 變量沒法實現這點。(然而,若是將值調整爲只從單個線程寫入,那麼能夠忽略第一個條件。) code

大多數編程情形都會與這兩個條件的其中之一衝突,使得 volatile 變量不能像 synchronized 那樣廣泛適用於實現線程安全。清單 1 顯示了一個非線程安全的數值範圍類。它包含了一個不變式 —— 下界老是小於或等於上界。

 


一旦一個共享變量(類的成員變量、類的靜態成員變量)被 volatile 修飾以後,那麼就具有了兩層語義:
  

在java線程併發處理中,有一個關鍵字volatile的使用目前存在很大的混淆,覺得使用這個關鍵字,在進行多線程併發處理的時候就能夠萬事大吉。

 

Java語言是支持多線程的,爲了解決線程併發的問題,在語言內部引入了 同步塊 和 volatile 關鍵字機制。

 

 

 


synchronized

同步塊你們都比較熟悉,經過 synchronized 關鍵字來實現,全部加上synchronized 和 塊語句,在多線程訪問的時候,同一時刻只能有一個線程可以用

 

synchronized 修飾的方法 或者 代碼塊。

 

 

 


volatile

用volatile修飾的變量,線程在每次使用變量的時候,都會讀取變量修改後的最的值。volatile很容易被誤用,用來進行原子性操做。

 

要使 volatile 變量提供理想的線程安全,必須同時知足下面兩個條件:

 

  • 對變量的寫操做不依賴於當前值。
  • 該變量沒有包含在具備其餘變量的不變式中。

 

實際上,這些條件代表,能夠被寫入 volatile 變量的這些有效值獨立於任何程序的狀態,包括變量的當前狀態。

 

第一個條件的限制使 volatile 變量不能用做線程安全計數器。雖然增量操做(x++)看上去相似一個單獨操做,實際上它是一個由讀取-修改-寫入操做序列組成的組合操做,必須以原子方式執行,而 volatile 不能提供必須的原子特性。實現正確的操做須要使 x 的值在操做期間保持不變,而 volatile 變量沒法實現這點。(然而,若是將值調整爲只從單個線程寫入,那麼能夠忽略第一個條件。)

 

大多數編程情形都會與這兩個條件的其中之一衝突,使得 volatile 變量不能像 synchronized 那樣廣泛適用於實現線程安全。清單 1 顯示了一個非線程安全的數值範圍類。它包含了一個不變式 —— 下界老是小於或等於上界。

 

 

 


一旦一個共享變量(類的成員變量、類的靜態成員變量)被 volatile 修飾以後,那麼就具有了兩層語義:


  1)保證了不一樣線程對這個變量進行操做時的可見性,即一個線程修改了某個變量的值,這新值對其餘線程來講是
    當即可見的。
  2)禁止進行指令重排序。
    volatile 本質是在告訴 jvm 當前變量在寄存器(工做內存)中的值是不肯定的,須要從主存中讀取;
    synchronized 則是鎖定當前變量,只有當前線程能夠訪問該變量,其餘線程被阻塞住。
  1.volatile 僅能使用在變量級別;
    synchronized 則可使用在變量、方法、和類級別的
  2.volatile 僅能實現變量的修改可見性,並不能保證原子性;
    synchronized 則能夠保證變量的修改可見性和原子性
  3.volatile 不會形成線程的阻塞;
    synchronized 可能會形成線程的阻塞。
  4.volatile 標記的變量不會被編譯器優化;

    synchronized 標記的變量能夠被編譯器優化
 

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息