Java併發之內存模型-JMM

1、總括
     併發編程模型主要處理兩個問題:線程之間如何通信及線程之間如何同步。通信:線程之間以何種機制來交換信息;同步:程序用來控制不同線程之間操作發生相對順序的機制。

     發生線程安全性的時機:
          變量存儲在內存中,變量的計算是在CUP中。如果線程A要對變量a進行計算,需要經過三步:1)把變量a從內存中讀取到CPU中,2)對變量a進行計算,3)把變量a寫入到內存中。當線程A執行到第二步時,線程B也要對變量a進行計算,這時B從內存中讀取到的值就是線程A寫入到內存之前的值,髒數據就此產生了。

     在命令式編程中主要有兩種通信機制:共享內存和消息傳遞。

2、共享內存的併發模型:
          通信:線程之間共享內存的公共狀態,線程之間通過讀-寫內存中的共享狀態來進行隱式通信。所謂隱式:線程什麼時候可以讀取共享狀態對程序員來說是透明的。
          同步:程序員必須指定某段代碼或某個方法必須在線程之間互斥執行。所以說同步是顯式的。

3、消息傳遞的併發模型:
          通信:線程之間沒有公共狀態,所以線程直接必須明確的發送消息進行顯式的通信
          同步:消息的發送必須在消息的接收之前,因此同步是隱式的。

4、JAVA
     Java的內存模型是共享內存,所以說Java的通信是隱式的,同步是顯式的。

5、Java中,所有的實例域、靜態域和數組元素都是存儲堆中的,堆內存在線程之間是共享的。本地變量(存儲在虛擬機棧的局部變量表中)、異常處理器參數不會在線程直接共享。
     另外:在JVM中,虛擬機棧、程序計數器、方法區存儲的數據都是線程私有的。隨線程而生,隨線程而滅。

6、Java線程之間的通信由JMM控制,JMM決定了一個線程對共享變量的寫入何時對另一個線程可見。JMM定義了線程和主內存之間的關係:線程之間的共享變量存儲在主內存(main memory)中,每個線程都有一個私有的本地內存(Local memory),本地內存中存儲了共享變量的副本。本地內存是JMM的一個抽象概念。

7、JMM抽象示意圖
     如果線程A要和線程B通信,需要經過以下2個步驟:
            1)線程A把本地內存中的變量更新到主內存中
            2)線程B把主內存中的變量讀取到本地內存中

8、下圖描述上面兩個步驟
本地線程A和B中都有主內存中共享變量的副本X。假設初始三個內存中的值都是0,線程A執行時把更新後X的值(假設是1)臨時保存到本地內存中。如果A要和B通信,線程A會把本地內存中修改後的值刷新到主內存中。隨後線程B到主內存中讀取線程A更新後的X值,此時線程B的本地內存中X的值也是1了。


9、關鍵詞
     編譯器優化重排序,指令級並行的重排序、內存系統重排序、處理器重排序、內存屏障。

10、volatile\Synchronized 關鍵詞會屏蔽重排序。

參考資料:infoq.com/深入理解JMM

































     

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