Java內存模型、內存間的交互操作、JVM運行時數據區以及和堆棧之間的關係

1、講Java內存之間的交互操作之前,首先得說一下Java的內存模型

因爲Java的內存模型定義了在虛擬機中將變量存儲到內存和從內存中取出變量的底層細節,它的主要目標是定義程序中各個變量的訪問規則,所以得先聊一聊Java內存模型

一提Java的內存大家應該會想到,那不就是平常說的堆、棧、方法區這些嗎?

其實並不是的,如上圖所示,平常說的堆、棧、方法區這些應該稱之爲JVM運行時數據區,而不是Java內存模型

Java內存模型將內存分爲了主內存和工作內存
Java內存模型規定所有的變量都存儲在主內存中,每個線程有自己的工作內存
主內存主要包括:堆和方法區,主內存是所有線程共享的
工作內存主要包括:該線程私有的棧和對主內存部分變量拷貝的寄存器(包括程序計數器和cpu高速緩存區)

2、Java內存模型規定了所有變量都存儲在主內存中,每個線程有自己的工作內存,線程對變量的所有操作都必須在自己的工作內存中進行,而不能直接讀寫主內存中的變量,不同線程之間也無法直接操作對方工作內存中的變量,線程間變量值的傳遞需要通過主內存來完成,Java內存模型是圍繞着在併發過程中如何處理原子性、可見性和有序性來建立的

3、JVM規範定義了線程對內存間交互的八種操作:

lock(鎖定):作用於主內存的變量,它把一個變量標識爲一個線程獨佔的狀態

unlock(解鎖):作用於主內存的變量,它把一個處於鎖定狀態的變量釋放出來,釋放後的變量纔可以被其他線程鎖定

read(讀取):作用於主內存的變量,它把一個變量的值從主內存傳送到線程中的工作內存,以便隨後的load動作使用

load(載入):作用於工作內存的變量,它把read操作從主內存中得到的變量值放入工作內存的變量副本中

use(使用):作用於工作內存的變量,它把工作內存中一個變量的值傳遞給執行引擎

assign(賦值):作用於工作內存的變量,它把一個從執行引擎接收到的值賦值給工作內存中的變量

store(存儲):作用於工作內存的變量,它把工作內存中的一個變量的值傳送到主內存中,以便隨後的write操作

write(寫入):作用於主內存的變量,它把store操作從工作內存中得到的變量的值寫入主內存的變量中
虛擬機必須保證以上的每一種操作都是原子的

在將變量從主內存讀取到工作內存中,必須順序執行read、load

要將變量從工作內存同步回主內存中,必須順序執行store、write

以上八種操作必須遵循以下八條規則:

(1):不允許read和load、store和write操作之一單獨出現。即不允許一個變量從主內存被讀取了,但是工作內存不接受,或者從工作內存回寫了但是主內存不接受。

(2):不允許一個線程丟棄它最近的一個assign操作,即變量在工作內存被更改後必須同步改更改回主內存。 

(3):工作內存中的變量在沒有執行過assign操作時,不允許無意義的同步回主內存。 

(4):在執行use前必須已執行load,在執行store前必須已執行assign。 

(5):一個變量在同一時刻只允許一個線程對其執行lock操作,一個線程可以對同一個變量執行多次lock,但必須執行相同次數的unlock操作纔可解鎖。

(6):一個線程在lock一個變量的時候,將會清空工作內存中的此變量的值,執行引擎在use前必須重新read和load。

(7):線程不允許unlock其他線程的lock操作。並且unlock操作必須是在本線程的lock操作之後。

(8):在執行unlock之前,必須首先執行了store和write操作。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章