本篇文章咱們來解決一個問題 這也是面試面的比較多的問題,進階階段(高級)通常都會問到。java
velatile變量怎麼保證可見性 爲何在併發狀況下沒法保證原子性?面試
比較懶了 摘了一段JVM原理的片斷來描述語義:併發
這裏只要記住尾部括號的三個點優化
1.從主內存到工做內存<讀>:每次使用變量前 先從主內存中刷新最新的值到工做內存,用於保證能看見其餘現場對變量修改的最新值線程
2.從工做內存到主內存<寫>:每次修改變量後必須馬上同步到主內存中,用於保證其餘線程能夠看到本身對變量的修改3d
3.指令重排序:保證代碼的執行順序和程序的執行順序一致。(併發環境下 代碼的執行順序與程序的執行順序有時並不一致,會出現串行的現象固有指令重排序優化一說。JAVA1.5以後完全修復了這個BUG在用volatile變量的時)blog
以上最多隻能保證可見性。但爲何不能保證原子性呢。排序
看下這個程序。執行後通常猜測會是200000.結果都是一個小於20的數字。爲何內存
經過javaP反編譯後發現一個現象 increaser方法有四個指令集構成get
getstatic指令還能保證其正確性,但在執行3,4兩步的時候 有可能race早已被其餘線程加大了,因此最後執行putstatic指令後有可能把已通過期的而且較小的值 同步回主內存形成數據不一致 因此並不能保證原子性