1. 程式人生 > >volatile和synchronized的區別?

volatile和synchronized的區別?

volatile 和 synchronized 都可以實現可見性。

volatile 關鍵字可以保證變數會直接從主記憶體中讀取,在寫入的時候也是直接寫入到主記憶體。

volatile 是基於 Memory Barrier (記憶體屏障)來實現的,也就是可以禁止指令重排序。如果一個變數是由 volatile 修飾的,那麼 Java 記憶體模型(JMM)在寫入這個變數之後會插入一條 writer-barrier 指令,同樣地在讀取這個變數之前也會插入一條 read-barrier 指令,這樣可以保證:

  1. 一個執行緒寫入一個變數a之後,其它任何執行緒訪問該變數都可以拿到最新值。
  2. 在寫入變數a之前的所有寫入操作對於其它執行緒也是可見的。

synchronized 關鍵字可以阻止其它執行緒獲取當前物件的監控鎖,這樣可以保證被 synchronized 關鍵字修飾的程式碼塊無法被其它執行緒訪問。

更重要的是,synchronized 關鍵字還會建立一個記憶體屏障,記憶體屏障指令保證了所有CPU操作結果都會直接刷到主存中,從而保證了操作的記憶體可見性,同時也使得先獲得這個鎖的執行緒的所有操作,都happens-before於隨後獲得這個鎖的執行緒的操作。

volatile和synchronized的區別?

  1. volatile本質是在告訴jvm當前變數在暫存器(工作記憶體)中的值是不確定的,需要從主存中讀取; synchronized 則是鎖定當前變數
    ,只有當前執行緒可以訪問該變數,其他執行緒被阻塞住。
  2. volatile 僅能使用在變數級別;synchronized則可以使用在變數、方法、和類級別。
  3. volatile僅能實現變數的修改可見性,不能保證原子性;而synchronized則可以保證變數的修改可見性和原子性
  4. volatile不會造成執行緒的阻塞;synchronized可能會造成執行緒的阻塞。
  5. volatile標記的變數不會被編譯器優化(禁止重排序);synchronized標記的變數可以被編譯器優化。