volatile實現原理--為什么實現了可見性卻不能保證原子性


本篇文章我們來解決一個問題  這也是面試面的比較多的問題,進階階段(高級)一般都會問到。

volatile變量怎么保證可見性  為什么在並發情況下無法保證原子性?

比較懶了  摘了一段JVM原理的片段來描述語義:

這里只要記住尾部括號的三個點

1.從主內存到工作內存<讀>:每次使用變量前  先從主內存中刷新最新的值到工作內存,用於保證能看見其他現場對變量修改的最新值

2.從工作內存到主內存<寫>:每次修改變量后必須立刻同步到主內存中,用於保證其他線程可以看到自己對變量的修改

3.指令重排序:保證代碼的執行順序和程序的執行順序一致。(並發環境下 代碼的執行順序與程序的執行順序有時並不一致,會出現串行的現象固有指令重排序優化一說。JAVA1.5之后徹底修復了這個BUG在用volatile變量的時)

以上最多只能保證可見性。但為什么不能保證原子性呢。

看下這個程序。執行后一般猜想會是200000.結果都是一個小於200000的數字。為什么

通過javaP反編譯后發現一個現象 increaser方法有四個指令集構成

 

 

 

getstatic指令還能保證其正確性,但在執行3,4兩步的時候 有可能race早已被其他線程加大了,所以最后執行putstatic指令后有可能把已經過期的並且較小的值 同步回主內存造成數據不一致 所以並不能保證原子性 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM