Java中 volatile 關鍵字的作用

Java 語言提供了一種稍弱的同步機制,即 volatile 變量,用來確保將變量的更新操作通知到其他線程。volatile
變量具備兩種特性,volatile 變量不會被緩存在寄存器或者對其他處理器不可見的地方,因此在讀取 volatile
類型的變量時總會返回最新寫入的值。

特點

變量可見性:其一是保證該變量對所有線程可見,這裏的可見性指的是當一個線程修改了變量的值,那麼新的值對於其他線程是可以立即獲取的。

禁止重排序:volatile 禁止了指令重排。

比 sychronized 更輕量級的同步鎖在訪問 volatile 變量時不會執行加鎖操作,因此也就不會使執行線程阻塞,因此 volatile 變量是一種比 sychronized 關鍵字更輕量級的同步機制。volatile 適合這種場景:一個變量被多個線程共享,線程直接給這個變量賦值。

當對非 volatile 變量進行讀寫的時候,每個線程先從內存拷貝變量到 CPU 緩存中。如果計算機有多個 CPU,每個線程可能在不同的 CPU 上被處理,這意味着每個線程可以拷貝到不同的 CPU cache 中。而聲明變量是 volatile 的,JVM 保證了每次讀變量都從內存中讀,跳過 CPU cache 這一步。

適用場景

值得說明的是對 volatile 變量的單次讀/寫操作可以保證原子性的,如 long 和 double 類型變量,但是並不能保證 i++這種操作的原子性,因爲本質上 i++是讀、寫兩次操作。在某些場景下可以代替 Synchronized。但是,volatile 的不能完全取代 Synchronized 的位置,只有在一些特殊的場景下,才能適用 volatile。總的來說,必須同時滿足下面兩個條件才能保證在併發環境的線程安全:

  1. 對變量的寫操作不依賴於當前值(比如 i++),或者說是單純的變量賦值(boolean flag = true)。
  2. 該變量沒有包含在具有其他變量的不變式中,也就是說,不同的 volatile變量之間,不能互相依賴。只有在狀態真正獨立於程序內其他內容時才能使用 volatile。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章