天天看點

Java虛拟機學習之Java記憶體模型

我們都站在巨人的肩膀上

  1. 概述

    • 記憶體模型:可以了解為在特定的操作協定下,對特定的記憶體或者或者緩存進行讀寫通路的過程抽象。
    • 這類協定有:MSI/MESI/MOSI/Synapse/Firefly以及Dragon/Protocol等
    • Java虛拟機學習之Java記憶體模型
  2. Java記憶體模型

    Java虛拟機規範中試圖定義一種Java記憶體模型來屏蔽掉各種硬體和作業系統的記憶體通路差異,以實作讓Java在各種平台下都能達到一緻的記憶體通路效果。
    1. 主記憶體和工作記憶體
      • Java記憶體模型定義的目标是 定義程式中各個變量的通路規則。
      • 此處的變量與Java程式設計中的變量有所差別,主要是非局部變量和方法參數,因為此二者屬于線程私有,不會存在競争關系,有競争關系的變量 如:執行個體變量、靜态字段和構成數組對象的元素。
      • Java記憶體模型規定了所有變量都存儲在主記憶體,
      • 每條線程還有自己的工作記憶體,線程的工作記憶體中儲存了被該線程使用到的主記憶體副本拷貝,線程對變量所有的操作都必須在工作記憶體中進行,不能在主記憶體中進行。
      • Java虛拟機學習之Java記憶體模型
    2. 記憶體間互動操作
      • Java記憶體模型中定義了8中操作來完成,虛拟機保證下面每一種操作都是原子性的、不可再分的(double和long有特殊規則)

        lock(鎖定):作用于主記憶體的變量,它把一個變量辨別為一條線程獨占的狀态。

        unlock(解鎖):作用于主記憶體的變量,它把一個處于鎖定狀态的變量釋放出來。

        read(讀取):作用于主記憶體的變量,他把一個變量值從主記憶體傳輸到線程的工作記憶體中,以便随後的load動作使用。

        load(載入):作用于工作記憶體的變量,它把read操作從主記憶體得到的變量值放入工作記憶體的變量副本中。

        use(使用):作用于工作記憶體的變量,它把工作記憶體中一個變量的值傳遞給執行引擎,每當虛拟機遇到一個需要使用到變量的值的位元組碼指令時将會執行這個操作。

        assign(指派):作用于工作記憶體的變量,它把一個從執行引擎接收到的值賦給工作記憶體的變量,每當虛拟機遇到一個給變量指派的位元組碼指令時執行這個操作。

        store(存儲):作用于工作記憶體的變量,它把工作記憶體中一個變量的值傳送到主記憶體中,以便随後的write操作使用。

        write(寫入):作用于主記憶體的變量,它把從store操作從工作記憶體中得到的變量的值放入主記憶體的變量中。

      • Java記憶體模型還規定了在執行上述8種疾病操作時必須滿足如下規則
        1. 不允許read和load、store和write操作之一單獨出現
        2. 不允許一個線程丢棄它的最近的assign
        3. 不允許一個線程無原因地(沒有發生任何assign操作)把資料從線程的工作記憶體同步回主記憶體
        4. 一個新的變量隻能在主記憶體中“誕生”,不允許在工作記憶體中直接使用一個未被初始化(load或assign)的變量
        5. 一個變量在同一個時刻隻允許一條線程對其進行lock操作,但lock操作可以被同一條線程執行多次,多次lock後,隻有相同次數的unlock操作,才能解鎖該變量
        6. 如果對一個變量執行lock操作,那将會清空工作記憶體中次變量的值,在執行引擎使用這個變量,需要重新執行load或assign操作初始化變量的值
        7. 如果一個變量沒有被lock,那也不能執行unlock,也不允許unlock其他線程鎖定的變量
        8. 對一個變量執行unlock操作之前,必須先把次變量同步回主記憶體(執行store、write操作)
    3. 對于volatile型變量的特殊規則(待更新)
    4. 對于long和double型變量的特殊規則(待更新)
    5. 原子性、可見性、有序性(待更新)
    6. 先行發生原則 (待更新)

繼續閱讀