為什麼說理解volatile關鍵字,才能理解線程操作的意義?對於初學者來說,volatile只是簡單的了解,只知道volatile作用就是「保證可見性」、「禁止指令重排序」,但是仍然存在一些誤區。
對於volatile關鍵字,可以說是Java虛擬機提供的最輕量級的同步機制,但是它「不能保證原子性」,所以很多程式設計師都習慣去避免使用它,遇到需要處理多線程數據競爭問題的時候一律使用 synchronized來進行同步。今天就花點時間聊一聊volatile關鍵字。
大家都是知道volatile是保證線程可見性的,所謂的可見性就是當一條線程修改了這個變量的值,然後新的值對其他所有線程都可以立即知道,這樣就是保證了線程安全。
但是對於volatile關鍵字,尤其在初學者開發時經常被誤解,認為「volatile變量對所有線程是立即可見性的,對volatile變量所有的寫操作都能立刻反映到其他線程之中。也就是說volatile變量在各個線程中是一致的,所以基於volatile變量的運算在並發下是線程安全的」,這句話論據部分並沒有錯。但是請看下一段:
雖然論據部分並沒有錯,但是由其論據並不能得出「基於volatile變量的運算在並發下是線程安全的」這樣的結論。我們可以從物理存儲的角度去分析,當各個線程的工作內存中volatile變量也可以存在不一致的情況,但由於每次使用之前都要先刷新到主內存,執行引擎看不到不一致的情況,因此可以認為不存在一致性問題。在Java運算操作符並非原子操作,這導致volatile變量的運算在並發下一樣是不安全的。
因此在使用volatile變量時,我們要知道它在運用運算場景中如何去使用,很多時候我們仍然要通過加鎖來保證原子性的。所以使用volatile需要滿足以下兩點:
變量不需要與其他的狀態變量共同參與不變約束運算結果並不依賴變量的當前值或確保只有單一的線程修改變量的值即可使用volatile變量還有一個作用就是「禁止指令重排序」。(指令重排序會干擾程序的並發執行)
白嫖不易,記得點個讚!
需要【Java複習腦圖、電子書】關注我,且私信「資料」集合獲取。