Java併發編程之驗證volatile的可見性

Java併發編程之驗證volatile的可見性

通過系列文章的學習,凱哥已經介紹了volatile的三大特性。1:保證可見性 2:不保證原子性 3:保證順序。那麼怎麼來驗證可見性呢?本文凱哥將通過代碼演示來證明volatile的可見性。

前期準備:

共享變量 number 初始值是0,然後修改後的值為100;

兩個線程,分別是:主線程Main以及線程名為A的線程

內部類:

Java併發編程之驗證volatile的可見性

可以看到有個方法將變量值修改成了100;

再來看看:

Java併發編程之驗證volatile的可見性


說明:

變量number不用volatile關鍵字修飾。主線程在運行後,啟動子線程。名字為線程A。然後線程A將變量number的值修改成了100後,主線程對number的進行判斷。如果numbr的值等於0的時候,就一直while循環。我們預期下結果:線程A修改完數據之後,輸出的是100呢還是0呢?最後運行結束這個是否會輸出呢?

我們來看看輸出的結果:

Java併發編程之驗證volatile的可見性

可以看到控制檯輸出的結果,線程A更新完變量的值之後在自己內部獲取到變量的值是更新後的,但是在主線程的工作緩存去獲取後,依然是0.因為主線程依然還在運行著(紅色按鈕一直紅色的),雖然線程A修改了共享變量的值,但是沒有人通知主線程你獲取的數據需要更新。這說明,在不用volatile修飾的時候,共享變量在線程A和主線程之間是不可見的。

我們再來試試使用volatile修飾共享變量後運行的結果。

使用volatile修飾變量

volatile int number = 0;

再來查看運行結果:

線程A 進入了。準備操作數據

線程A 更新數據完成。更新後的值為:100

==============main====運行結束.主線程Main獲取到的值為:100

Java併發編程之驗證volatile的可見性


結論:

我們可以看到,運行結束語句也輸出了。並且主線程獲取到number的值就是修改後的100.

這次操作和上次操作唯一區別就是變量number添加了volatile關鍵字來修飾,但是主線程竟然能夠獲取到線程A修改後的數據,從而證明了volatile能夠保證共享變量在其他線程的可見性。

Volatile第二個特性:不保證原子性的證明,歡迎繼續學習凱哥【凱哥Java:kaigejava】下一篇文章《Java併發編程之驗證volatile不能保證原子性》。


分享到:


相關文章: