線程的記憶體結構圖 一、主記憶體與工作記憶體 1.Java記憶體模型的主要目標是定義程式中各個變數的訪問規則。此處的變數與Java編程時所說的變數不一樣,指包括了實例欄位、靜態欄位和構成數組對象的元素,但是不包括局部變數與方法參數,因為它們是線程私有的,不會被共用。 2.Java記憶體模型中規定了所有的變數都 ...
線程的記憶體結構圖
一、主記憶體與工作記憶體
1.Java記憶體模型的主要目標是定義程式中各個變數的訪問規則。此處的變數與Java編程時所說的變數不一樣,指包括了實例欄位、靜態欄位和構成數組對象的元素,但是不包括局部變數與方法參數,因為它們是線程私有的,不會被共用。
2.Java記憶體模型中規定了所有的變數都存儲在主記憶體中,每條線程還有自己的虛擬記憶體。線程的虛擬記憶體中保存了該線程使用到的變數到主記憶體副本拷貝。線程對變數的所有操作(讀取、賦值)都必須在自己的虛擬記憶體中進行,而不能直接讀寫主記憶體中的變數。不同線程之間無法直接訪問對方虛擬記憶體中的變數,線程間變數值的傳遞均需要在主記憶體來完成。
二、記憶體間交互操作
關於主記憶體與工作記憶體之間的具體交互協議,即一個變數如何從主記憶體拷貝到工作記憶體、如何從工作記憶體同步到主記憶體之間的實現細節,Java記憶體模型定義了以下八種操作來完成:
- lock(鎖定):作用於主記憶體的變數,把一個變數標識為一條線程獨占狀態。
- unlock(解鎖):作用於主記憶體變數,把一個處於鎖定狀態的變數釋放出來,釋放後的變數才可以被其他線程鎖定。
- read(讀取):作用於主記憶體變數,把一個變數值從主記憶體傳輸到線程的工作記憶體中,以便隨後的load動作使用
- load(載入):作用於工作記憶體的變數,它把read操作從主記憶體中得到的變數值放入工作記憶體的變數副本中。
- use(使用):作用於工作記憶體的變數,把工作記憶體中的一個變數值傳遞給執行引擎,每當虛擬機遇到一個需要使用變數的值的位元組碼指令時將會執行這個操作。
- assign(賦值):作用於工作記憶體的變數,它把一個從執行引擎接收到的值賦值給工作記憶體的變數,每當虛擬機遇到一個給變數賦值的位元組碼指令時執行這個操作。
- store(存儲):作用於工作記憶體的變數,把工作記憶體中的一個變數的值傳送到主記憶體中,以便隨後的write的操作。
- write(寫入):作用於主記憶體的變數,它把store操作從工作記憶體中一個變數的值傳送到主記憶體的變數中。
如果要把一個變數從主記憶體中複製到工作記憶體,就需要按順尋地執行read和load操作,如果把變數從工作記憶體中同步回主記憶體中,就要按順序地執行store和write操作。
三、多線程的三個特性
1、原子性(Atomicity)
原子性是指在一個操作中就是cpu不可以在中途暫停然後再調度,既不被中斷操作,要不執行完成,要不就不執行。和事物的原子性一致。
2、可見性(Visibility)
可見性就是指當一個線程修改了線程共用變數的值,其它線程能夠立即得知這個修改。從多線程記憶體間的交互我們知道,共用數據都是從主記憶體拷貝副本在虛擬記憶體操作,最後寫入主記憶體,就會造成線程不安全。
如果在變數讀取前從主記憶體刷新變數值,可以利用這種依賴主記憶體作為傳遞媒介的方法來實現可見性。
3、有序性(Ordering)
線程的有序性指兩個方面:如果在本線程內觀察,所有操作都是有序的;如果在一個線程中觀察另一個線程,所有操作都是無序的。前半句是指“線程內表現為串列語義”,後半句是指“指令重排序”現象和“工作記憶體中主記憶體同步延遲”現象。
四、同步機制
介紹volatile、synchronized、final