我是
方圓
,循序漸進,按部就班
1. 什麼是JMM呀?
JMM是Java Memory Mode
的縮寫,譯成中文是Java內存模型。它定義了Java虛擬機在計算機內存中的工作方式,JMM是隸屬於JVM的。
從抽象的角度來看,JMM定義了線程和主內存之間的抽象關係
,線程之間的共享變量存儲於主內存中,每個線程又都有自己的工作內存。而實際上,工作內存並不存在,僅僅是一個抽象的概念,它涵蓋了緩存、寫緩衝區、寄存器及其他的硬件和編譯器優化。
2. JVM對Java內存模型的實現
- 在JVM內部,Java內存模型把內存分成了兩部分,
線程棧區和堆區
JVM中運行的每條線程都有自己的線程棧
,線程棧包含了當前線程執行的方法調用相關信息,我們也把它叫做調用棧。
3. JMM帶來的問題
可見性問題
不同線程從主內存中獲取值,並存儲在自己的工作內存中。若對工作內存的進行修改之後,沒有及時將其flush到主內存中,這就導致了不同線程中共享變量值不同的問題。(可以通過加鎖和關鍵字volatile解決)
競爭問題
線程A和線程B共享一個對象obj。假設線程A從主存讀取Obj.count變量到自己的CPU緩存,同時,線程B也讀取了Obj.count變量到它的CPU緩存,並且這兩個線程都對Obj.count做了加1操作。此時,Obj.count加1操作被執行了兩次,不過都在不同的CPU緩存中。如果這兩個加1操作是串行執行
的,那麼Obj.count變量便會在原始值上加2,最終主存中的Obj.count的值會是3。然而下圖中兩個加1操作是並行的
,不管是線程A還是線程B先flush計算結果到主存,最終主存中的Obj.count只會增加1次變成2,儘管一共有兩次加1操作。 (解決上面的問題我們可以使用java synchronized代碼塊)