Java併發編程之驗證volatile指令重排-理論篇

Java併發編程之驗證volatile指令重排-理論篇

Java併發包下的類中大量使用了volatile關鍵字。通過之前文章介紹,大家已經知道了volatile的三大特性:共享變量可見性;不保證原子性;禁止指令重排後順序性。通過前面兩篇文章我們通過代碼驗證了前兩個特性,本文我們就來驗證禁止指令重排保證順序性。

指令重排序的生活例子

去餐廳吃飯預定位置的的時候。假設要去A餐廳吃飯,A餐廳有前臺B、服務員C以及老闆D。如果就只有你一個人去吃飯的時候,你給前臺或者給服務器或者給老闆說一聲把2號桌預定了,半小時後過來。餐廳在為了2小時內就你一個人去吃飯。那麼OK,沒問題,別說等半個小時,就是等一個小時,2號桌還是你的。

但是,如果現在是吃飯高峰期,很多人來吃飯,你給前臺說了,前臺忙著沒有及時給服務員或者沒有給老闆說,這個時候有個路人甲來吃飯,剛好看到2號桌沒人,老闆或者服務員就讓他就坐2號桌吃飯了。那麼,等你過來的時候,2號桌已經有人了。這個時候對於你來說,這個結果就不是你想要的了。

上面案例,如果從計算機執行指令角度來分析的話,你要到2號桌吃飯,這是預期結果。餐廳A就相當於是處理器,前臺B就相當於是編譯器,服務員C和老闆D就是指令和內存系統。如果你預定的時間點不是吃飯高峰期或者沒有人去餐廳A吃飯。那麼你就相當於是一個線程。就是單線程的。老闆、前臺、服務員怎麼安排都可以。因為只有你一個2號桌肯定是你的。這是單線程情況下。預期結果與實際結果就是一致的。

如果你預定的時間點是吃飯高峰期,很多人來吃飯(很多線程),這個時候為了餐廳效益,無論是前臺還是服務員或者是老闆都會對你的位置進行重排序。在你沒有來的時候,會安排其他人到你預定的位置吃飯。如果其他人在你的位置吃飯,這個時候你再來吃飯,那麼實際結果和預期結果就不一樣了。這個時候餐廳應該做出相應的賠償。為了解決這種賠償問題,老闆就想到了一個方案。做個牌子放在客人預定的桌子上。

當前臺或者是服務員或者是老闆看到餐桌上放的這個牌子,就知道這個位置不能再調動了。其中這個放在餐桌上的牌子就是特殊類型的內存屏障了。

示意圖如下:

Java併發編程之驗證volatile指令重排-理論篇

再來舉個更常見的例子:

考試,在考試的時候老師會告訴我們,先做會做的,不會做的放到後面做。假設出題老師出題順序是1-5,但是考試會根據自己實際情況做題順序有可能是1、2、4、5、3或者是1、3、4、5、2等等。如果把出題老師看著是寫代碼的程序員,題目的順序是代碼一行一行的順序,你的老師會告訴你先做會做的,此時老師就相當於是編譯器,會排序一次。然後你自己做的時候又會進行重新排序,你自己就相當於是處理器又排序了一次。

上面兩個現實生活中的案例,我們弄明白後,再來看看在計算機中指令重排問題,就很容易理解了。

指令重排

我們程序員編寫的代碼在JVM執行的時候,為了提高性能,編譯器和處理器都會對代碼編譯後的指令進行重排序。分為3種:

1:編譯器優化重排:

編譯器的優化前提是在保證不改變單線程語義的情況下,對重新安排語句的執行順序。

2:指令並行重排:

如果代碼中某些語句之間不存在數據依賴,處理器可以改變語句對應機器指令的順序

如:int x = 10;int y = 5;對於這種x y之間沒有數據依賴關係的,機器指令就會進行重新排序。但是對於:int x = 10; int y = 5; int z = x+y;這種的,因為z和x y之間存在數據依賴(z=x+y)關係。在這種情況下,機器指令就不會把z排序在xy前面。

3:內存系統的重排序

通過之前的學習,我們知道了處理器和主內存之間還存在一二三級緩存。這些讀寫緩存的存在,使得程序的加載和存取操作,可能是亂序無章的。

指令重排序的流程圖

通過上面介紹,我們可以知道從程序員寫的Java源碼到處理器真正實際執行的指令序列,會經歷如下圖的過程:


Java併發編程之驗證volatile指令重排-理論篇

執行順序:

源碼編譯器優化重排序(第一次排序) 指令重排序(第二次)內存重排序(第三次) 最終指向的指令。

無論是第一次編譯器的重排序還是第二、三次的處理器重排序。這些重排序當在多線程的場景下可能會出現線程可見性的問題。

如在多線程的情況下,單例模式就不安全了。

為了解決這個問題,JMM允許編譯器在生成指令順序的時候,可以插入特定類型的內存屏障來禁止指令重排序。

當一個變量使用volatile修飾的時候,volatile關鍵字就是內存屏障。當編譯器在生成指令順序的時候,發現了volatile,就直接忽略掉。不再重排序了。

示意圖:

Java併發編程之驗證volatile指令重排-理論篇

證明volatile禁止指令重排演示代碼,歡迎繼續學習下一篇文章


分享到:


相關文章: