1. 程式人生 > 其它 >深究可見性,原子性,有序性的解決方案之volatile原始碼解析

深究可見性,原子性,有序性的解決方案之volatile原始碼解析

   上節java記憶體模型(jmm)概念初探大致瞭解了由於cpu的快速發展,導致的越來越複雜的記憶體模型誕生,java記憶體模型相當於是底層記憶體模型的對映(實際並不是一一對映,但可以借鑑理解),也是衍生出併發三大特性:可見性,原子性,有序性,在多執行緒情況下這些特性也有多種方式可以保證,如volatile,synchronized關鍵字等,這一節從原始碼角度,分析volotile關鍵字。

  

   private static int int1;
     private static volatile int int2;public static void main(String[] args) throws InterruptedException {
        
for (int i = 0; i < 10000; i++) { increase(i); } Thread.sleep(1000); } private static void increase(int i){ int1= i+1; int2= i+2; }

首先看java程式碼,這裡我用了2個變數,一個是volatile,另一個是普通的,我們看彙編列印:

 

 

 可以看到兩者卻別在於加了volatile關鍵字的多了一個lock 的指令,lock指令通過鎖匯流排的方式(新的處理器以及改為快取鎖定的方式,就是鎖住記憶體地址塊)會讓緊跟在後面的指令變成原子操作,上面的lock addl $0x0其實就是lock後面又加了一個0,就是為了既不改變值,還能達到原子操作的效果。而且lock指令規定了要等前面的指令全部執行結束,然後把資料全部更新到主存,想一想這樣是不是新的執行緒過來讀到的狀態都是最新的,但是之前就已經有快取的怎麼辦呢?這個咱們的現在的一致性協議如MESI會保證其他Cache失效,從而到達資料一致的效果。lock指令也保證了前後指令相對lock來說有序。相當於是保證了可見性,原子性和有序性。但是為什麼都說volatile又無法保證原子性呢,因為當你需要對volatile進行計算操作,那就不是一個指令可以完成的了,而volatile顯然不具備synchronized那樣可以對整個臨界區程式碼都能保證原子性的能力,所以一般說volatile不具備原子性。

未完待續。。。