Java記憶體模型簡介
首先要明確記憶體模型指什麼。書中的定義是:在特定的操作協議下,對特定記憶體和快取記憶體進行讀寫訪問的過程抽象。 |
可以知道,記憶體模型就是來規定如何對記憶體/快取進行讀寫操作的。所以Java記憶體模型,就是用來定義程式對Java記憶體的的訪問規則。進一步說, Java記憶體模型就是定義程式中變數(靜態變數、陣列物件元素等,不包括區域性變數、方法引數)的訪問規則。
- 所有變數儲存在主記憶體中;
- 每個執行緒都有自己的工作記憶體,且對變數的操作都是在工作記憶體中進行;
- 不同執行緒之間無法直接訪問彼此工作記憶體中的變數,要想訪問只能透過主記憶體來傳遞。
具體變數從主記憶體到工作記憶體,以及從工作記憶體轉回主記憶體的實現細節,由下面八個原子性的操作完成:
-
- lock:作用於主記憶體變數,將該變數標識為一個執行緒獨佔的狀態
- unlock:作用於主記憶體變數,將獨佔狀態釋放
- read:作用於主記憶體變數,將值複製到工作記憶體中
- load:作用於工作記憶體中的變數,將值放到工作記憶體中的變數副本中
- use:作用於工作記憶體中的變數,將值傳給執行引擎
- asign:作用於工作記憶體中的變數,將執行引擎中的值賦給工作記憶體中的變數
- store:作用於工作記憶體中的變數,將值傳給主記憶體
- write:作用於主記憶體中的變數,將工作記憶體中返回的值放到主記憶體變數中
同時還對上述八個操作進行了一些細節的要求,比如read/load、store/write必須成對出現,未執行過lock的變數不能執行unlock操作等。
劃重點,此處面試常遇到的問題就是對於volatile關鍵字的解讀。
此關鍵字修飾的變數具有兩種效果:1、保證執行緒間的可見性;2、阻止指令重排序
對於1的實現,它保證load與use必須相鄰呼叫,即要use這個變數,必定先執行read/load,這樣每次都能獲取到最新的變數值;它又保證asign與store必須相鄰呼叫,即在工作記憶體中將該變數改了之後,必定會先同步到主記憶體中。這樣,volatile關鍵字實現了可見性。至於阻止指令重排序,還是移步《深入理解Java虛擬機器》一書吧,貧道水平有限,就不在這裡說了。
從另一個角度來分析,Java記憶體模型是圍繞著在併發過程中如何處理原子性、可見性、有序性來建立的。
原子性:八個原子性操作,以及synchronized(lock/unlock未直接開放給使用者,synchronized透過monitorenter跟monitorexit指令呼叫的lock/unlock操作)
- 可見性:volatile、synchronized、final這三個關鍵字均透過不同方式實現了可見性
- 有序性:volatile、synchronized 這兩個關鍵字保證有序性,同時還有先行發生(happens-before)原則來保證隱含的預設有序性
下面說說happens-before先行發生原則,先行發生原則用通俗語言表述就是:如果操作A在操作B之前發生,那麼A產生的影響B同樣能觀測到。那麼問題來了,先行發生原則都有哪些呢?同樣有八條,如下:
- 程式次序規則:同一個執行緒中按照程式碼的順序依次執行
- 管程鎖定規則:對於同一個鎖,unlock先行發生於後面的lock,即unlock了才會lock
- volatile變數規則:對一個volatile變數的寫操作先行發生於後面對該變數的讀操作,即寫完了才會讀
- 執行緒啟動規則:一個執行緒的start()方法先行發生於此執行緒的任何一個動作
- 執行緒終止規則:一個執行緒的所有動作先行發生於該執行緒的終止檢測
- 執行緒中斷規則:對一個執行緒interrupt()方法的呼叫先行發生於執行緒的中斷檢測Thread.interrpted()
- 物件終結規則:物件的初始化完成先行發生於finalize()方法
- 傳遞性:顧名思義,A先行發生於B,B先行發生於C,則A一定先行發生於C
Java記憶體模型基本就這些內容,如果都掌握了的話,非一線網際網路公司基本都能應對自如了(因為一線網際網路公司貧道本人也沒進去><)。
原文連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31559985/viewspace-2656703/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Java記憶體模型 - 簡介Java記憶體模型
- Java 記憶體模型Java記憶體模型
- Java記憶體模型Java記憶體模型
- JVM記憶體結構、Java記憶體模型和Java物件模型JVM記憶體Java模型物件
- Java記憶體區域和記憶體模型Java記憶體模型
- 記憶體管理簡介記憶體
- Java記憶體模型FAQ(一) 什麼是記憶體模型Java記憶體模型
- JMM Java 記憶體模型Java記憶體模型
- Java記憶體模型-(1)Java記憶體模型
- Java物件記憶體模型Java物件記憶體模型
- Java的記憶體模型Java記憶體模型
- 探索Java記憶體模型Java記憶體模型
- 理解Java記憶體模型Java記憶體模型
- Java記憶體模型是什麼,為什麼要有Java記憶體模型,Java記憶體模型解決了什麼問題?Java記憶體模型
- 淺談JVM記憶體結構 和 Java記憶體模型 和 Java物件模型JVM記憶體Java模型物件
- 淺談Java記憶體模型Java記憶體模型
- java記憶體模型——重排序Java記憶體模型排序
- Java記憶體模型之前奏Java記憶體模型
- Java基礎:記憶體模型Java記憶體模型
- java記憶體垃圾回收模型Java記憶體模型
- Java記憶體模型_基礎Java記憶體模型
- Java記憶體模型_重排序Java記憶體模型排序
- Java記憶體模型_volatileJava記憶體模型
- 同步和Java記憶體模型Java記憶體模型
- 這樣看java記憶體模型其實很簡單Java記憶體模型
- 持久記憶體指令(PMDK)簡介記憶體
- Concurrency(五: Java記憶體模型)Java記憶體模型
- 什麼是Java記憶體模型?Java記憶體模型
- java記憶體模型的實現Java記憶體模型
- Java 執行緒記憶體模型Java執行緒記憶體模型
- Java記憶體模型的基礎Java記憶體模型
- 深入淺出Java記憶體模型Java記憶體模型
- 什麼是Java記憶體模型Java記憶體模型
- Java 記憶體模型 JMM 深度解析Java記憶體模型
- Java記憶體模型及volatileJava記憶體模型
- Java 記憶體模型 JMM 淺析Java記憶體模型
- OpenJDK修訂Java記憶體模型JDKJava記憶體模型
- Java記憶體模型深度解析:鎖Java記憶體模型