本篇文章我們來解決一個問題 這也是面試面的比較多的問題,進階階段(高級)一般都會問到。
volatile變量怎么保證可見性 為什么在並發情況下無法保證原子性?
比較懶了 摘了一段JVM原理的片段來描述語義:
這里只要記住尾部括號的三個點
1.從主內存到工作內存<讀>:每次使用變量前 先從主內存中刷新最新的值到工作內存,用於保證能看見其他現場對變量修改的最新值
2.從工作內存到主內存<寫>:每次修改變量后必須立刻同步到主內存中,用於保證其他線程可以看到自己對變量的修改
3.指令重排序:保證代碼的執行順序和程序的執行順序一致。(並發環境下 代碼的執行順序與程序的執行順序有時並不一致,會出現串行的現象固有指令重排序優化一說。JAVA1.5之后徹底修復了這個BUG在用volatile變量的時)
以上最多只能保證可見性。但為什么不能保證原子性呢。
看下這個程序。執行后一般猜想會是200000.結果都是一個小於200000的數字。為什么
通過javaP反編譯后發現一個現象 increaser方法有四個指令集構成
getstatic指令還能保證其正確性,但在執行3,4兩步的時候 有可能race早已被其他線程加大了,所以最后執行putstatic指令后有可能把已經過期的並且較小的值 同步回主內存造成數據不一致 所以並不能保證原子性