在Java中,volatile是個很高層面的規范,保證了指令不會被重排序+對volatile變量的寫使得當前cpu緩存中的所有變量寫回到主存中,從而保證了內存可見性。
具體的實現是靠JVM和cpu(還有操作系統?)合作實現的,不管cpu有沒有mesi協議,用了volatile,JVM都會保證可見性,只不過實現方式是不一樣的。
有個問題就是:mesi似乎已經保證了線程之間的可見性,那么在實現了mesi協議的cpu上,volatile關鍵字其實是不是沒用的?
答案是:還是有用的,就算在實現了mesi的cpu上,volatile一樣不可或缺。除了禁止指令重排序的作用外,由於mesi只是保證了L1-3 的cache之間的可見性,但是cpu和L1之間
還有像storebuffer之類的緩存,而volatile規范保證了對它修飾的變量的寫指令會使得當前cpu所有緩存寫到被mesi保證可見性的L1-3cache中。(具體的實現,以X86體系為例,
volatile會被JVM生成帶lock前綴的指令)。
扯兩句遠的:
1、i++的問題是寫更新丟失的問題,跟現在說的沒關系,要用cas解決。
2、cas其實不是原子性操作,要讀一次,再寫一次。但是可以用MESI實現原子性:讀一次發現是目標值,寫的時候判斷是不是I就可以。mesi實現其他原子性操作也是這個思路。