可以保證多執行緒環境下共享變數的可見性
透過增加記憶體屏障來防止多個指令之間的重排序
可見性是指當一個執行緒對於共享變數的修改,其他執行緒可以立刻看到修改之後的一個值,可見性本質上由幾個面向造成的
cpu層面的高速緩存,在cpu裡面呢設計了三級快取去解決cpu運算效率和記憶體IO效率的問題,但是它也帶來快取一致性的一個問題,而在多執行緒執行的情況下呢,快取一致性的問題就會導致可見性的問題,所以,對於增加了volatile
關鍵字的一個修飾的共享變量,jvm虛擬機會自動去增加一個#lock彙編指令,而這個指令會去根據不同的cpu型號會自動添加總線鎖
或緩存鎖定
#匯流排鎖是鎖定cpu前端匯流排,從而去導致在同一個時刻,只能有一個執行緒和記憶體通信,這樣就避免了多執行緒並發造成的可見性問題
#快取鎖是對匯流排鎖的最佳化,因為總線鎖導致cpu的使用效率大幅度下降,所以,快取鎖只針對於cpu三級快取中的目標資料去加鎖,而快取鎖使用MESI快取一致性協定來實現的
指令重排序指令在編寫的資料順序和執行順序是不一致的,從而在多執行緒環境下導致可見性問題,指令重排序本質上是一種效能最佳化的手段,指令重排序來自於幾個面向
cpu層面針對於MESI協定
更進一步的最佳化,去提升cpu一個利用率,他引入一個叫StoreBuffer
的一個機制,而這種最佳化機制呢,會導致cpu的亂序執行,為了避免這樣的問題,cpu提供記憶體屏障指令,上層應用可以在適當的地方去插入記憶體屏障,去避免cpu指令重排序的一個問題
編譯器在編譯的過程中,在不改變單線程語義和程序正確性的前提下,對指令進行合理的重排序,從而去優化整體的一個效能,所以共享變數增加了volatile
關鍵字那麼編譯器層面就不會觸發編譯器的最佳化,同時在jvm裡面呢,他會插入記憶體屏障指令來避免重排序的問題
除了volatile
關鍵字,從JDK5開發,JMM就使用一種Happens-Before
的模型去描述多執行緒可見性的一個關係,也就是兩個操作之間具備Happens-Before
關係,那麼這兩個操作具備可見性的一個關係,不需要再額外去考慮增加volatile
關鍵字來提供可見性的一個保障
以上是Java中的volatile關鍵字有什麼用的詳細內容。更多資訊請關注PHP中文網其他相關文章!