volatile 字段

有時僅僅爲了讀寫一個或者兩個實例域就使用同步的話,顯得開銷過大;而volatile關鍵字爲實例域的 同步訪問提供了免鎖的機制。如果聲明一個域爲volatile,那麼編譯器和虛擬機就知道該域是可能被另一個 線程併發更新的。

 

Java中的堆內存用來存儲對象實例,堆內存是被所有線程共享的運行時內存區域,因此,它存在內存可 見性的問題。而局部變量、方法定義的參數則不會在線程之間共享,它們不會有內存可見性問題,也不受 內存模型的影響

 

原子性、可見性和有序性

 

(1)原子性

對基本數據類型變量的讀取和賦值操作是原子性操作,即這些操作是不可被中斷的,要麼執行完畢, 要麼就不執行。

(2)可見性 可見性,是指線程之間的可見性,一個線程修改的狀態對另一個線程是可見的。也就是一個線程修改 的結果,另一個線程馬上就能看到

(3)有序性 Java內存模型中允許編譯器和處理器對指令進行重排序,雖然重排序過程不會影響到單線程執行的正確 性,但是會影響到多線程併發執行的正確性。這時可以通過volatile來保證有序性,除了volatile,也可以通 過synchronized和Lock來保證有序性。我們知道,synchronized和Lock保證每個時刻只有一個線程執行同步代 碼,這相當於是讓線程順序執行同步代碼,從而保證了有序性。 

 

當一個共享變量被volatile修飾之後,其就具備了兩個含義,一個是線程修改了變量的值時,變量的新 值對其他線程是立即可見的。換句話說,就是不同線程對這個變量進行操作時具有可見性。另一個含義是 禁止使用指令重排序。

什麼是重排序呢?重排序通常是編譯器或運行時環境爲了優化程序性能而採 取的對指令進行重新排序執行的一種手段。重排序分爲兩類:編譯期重排序和運行期重排序,分別對應編 譯時和運行時環境。

volatile不保證原子性 

volatile保證有序性 

 

與鎖相比,volatile變量是一種非常簡單但同時又非常脆弱的同步機制,它在某些情況下將提供優於鎖 的性能和伸縮性。如果嚴格遵循volatile的使用條件,即變量真正獨立於其他變量和自己以前的值,在某些 情況下可以使用volatile代替synchronized來簡化代碼。然而,使用volatile的代碼往往比使用鎖的代碼更加容 易出錯。

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章