JMM(Java內存模型)中的核心概念

轉自   http://guibin.iteye.com/blog/1172731

在JLS-Java Language Specification的17.4節詳細描述了JMM(Java Memory Model),這個文檔從語言學和實現JVM的角度講非常棒,但是對於我們這些應用開發者而言理解其中的細節就有些問題。 

本文中不再重複spec中那些正式的細節,下面將列出一些重要的原則和基本的概念,如synchronizes-with,happens-before。這兩個概念和麪向對象設計中的兩個概念has-a,is-a很相似,Happens-before 和 synchronizes-with是用來建立和理解Java 併發的基礎。 

  • HAPPENS-BEFORE:這個關係用來指示“一段代碼在其他代碼開始執行前已經完全執行完畢”。
  • SYNCHRONIZES-WITH:這個關係表示一個行爲在發生時,它首先把要操作的那些對象同主存同步完畢之後才繼續執行。


JMM有以下主要的規則: 
  • An Unlock operation on a monitor synchronizes-with later lock operations. 當針對一個監控對象執行解鎖操作時,首先synchronizes-with隨後的鎖操作。即當要解鎖時,首先此操作會把它範圍內的對象與主存同步,然後解鎖,之後纔會執行隨後其他的鎖操作。
  • A write to a volatile variable synchronizes-with later reads of the variable. 當寫一個volatile變量時,首先synchronizes-with隨後的讀此變量的操作。即當寫完一個volatile變量後,JVM會首先將此變量與主存同步,然後才執行隨後的讀volatile變量操作。當然也從主存讀了。
  • If an action A synchronizes-with action B, then A happens-before B. 如果時行爲A synchronizes-with 行爲B,那麼行爲A happens-before B。
  • If A comes before B in program order within a thread, then A happens-before B. 在同一個線程中如果程序中A在B之前,那麼A也一定發生在B之前。
  • The completion of a constructor happens-before the finalizer for that object starts to run. 完成構造函數會發生在此對象的finalizer啓動之前,即在對一個對象回收前,此對象必須已經構造完畢。
  • An action which starts a Thread synchronizes-with the first action of the new Thread. 創建了一個新線程的行爲synchronizes-with這個線程的第一個操作。即創建完新線程後,JVM首先要把這個線程的信息同步給主存,然後纔可以執行這個線程內部的其他操作。
  • Thread.join() synchronizes-with the last (and all other) actions in the thread being joined. Thread.join()函數synchronizes-with被join的線程內部的所有其他操作。即執行Thread.join()之後JVM首先會把信息跟主存同步,然後纔會繼續執行被join線程內部的其他操作。
  • (Transitivity) If X happens-before Y, and Y happens-before Z, then X happens-before Z. 傳遞性,即X在Y之前執行,Y在Z之前執行,那麼X會在Z之前執行。


前面的兩條規則是說:“releases happen before acquires;” (解鎖發生在獲取鎖之前)即:一個線程拿着鎖,當寫操作完畢後首先釋放鎖,然後這個鎖才能被其他線程獲得 

以上的這些規則是JMM所做的基本保證,在真正的JVM實現中會有更多更好的規則。 

發佈了48 篇原創文章 · 獲贊 33 · 訪問量 31萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章