1. 程式人生 > >“Happens-before”規則和 8種記憶體互動的原子操作

“Happens-before”規則和 8種記憶體互動的原子操作

“Happens-before”規則:

用於保證有序性,假如兩個操作之間不存在以下關係,並且無法從以下規則推匯出,那麼虛擬機器可以對去進行隨意的重排序:

  • 程式次序規則:在一個執行緒內,按照程式程式碼的順序,書寫在前面的操作現行發生於書寫在後面的操作。準確的說,應該是控制流的順序而不是程式程式碼順序,因為要考慮分支迴圈的等結構。
  • 管程鎖定規則: 一個unlock操作現行發生於後面一個對同一個鎖的lock操作。這裡必須強調的是同一個鎖,而”後面”是指時間上的先後順序
  • volatile變數規則:對一個volatitle變數的寫操作先發生於後面的對這個變數的讀操作,這裡的”後面”是指時間上的。
  • 執行緒啟動規則
    :Thread物件的start()方法先發生於此現成的每一個動作。
  • 執行緒終止規則: 執行緒中的所有操作都先發生於對此執行緒的終止檢測,我們可以通過Thread.join()方法結束、Tread.isAlive()方法的返回值等手段檢測到執行緒已經終止執行。
  • 執行緒中斷規則:對執行緒interupt()方法的呼叫先行發生於被中斷執行緒的程式碼檢測到中斷時間的發生。可以通過Tread.interupted()方法檢測到是否發生了中斷。
  • 物件最終規則:一個物件的初始化完成(建構函式執行結束)先行發生於它的finalize()方法的開始。
  • 傳遞性:如果操作A先行發生於操作B,那麼B現行發生於操作C,那就可以的操作A現行發生於操作C的結論。

JAVA記憶體模型中定義了以下8種操作來完成工作記憶體與主存的互動,虛擬機器保證了每一種操作都是原子操作、不可再分的。(double 和 long 型別變數在部分平臺允許例外,主要與其在記憶體中所佔位數有關。)

  • lock:作用於主記憶體,把變數標識為執行緒獨佔狀態。
  • unlock:作用於主記憶體,解除獨佔狀態。
  • read:作用主記憶體,把一個變數的值從主記憶體傳輸到執行緒的工作記憶體。
  • load:作用於工作記憶體,把read操作傳過來的變數值放入工作記憶體的變數副本中。
  • use:作用工作記憶體,把工作記憶體當中的一個變數值傳給執行引擎。
  • assign:作用工作記憶體,把一個從執行引擎接收到的值賦值給工作記憶體的變數。
  • store:作用於工作記憶體的變數,把工作記憶體的一個變數的值傳送到主記憶體中。
  • write:作用於主記憶體的變數,把store操作傳來的變數的值放入主記憶體的變數中。