天天看點

java常見面試題:聊聊你對java記憶體模型的看法 @抖音短視訊

作者:程式員葉偉

java程式員常見面試題:Java記憶體模型到底是個什麼鬼?

90%以上的同學可能都不太清楚Java記憶體模型到底是個什麼東西。雖然在工作中可能或多或少都會用到多線程,也會接觸到對同一個變量的并發通路。大家應該都會想到syntronized對吧?但是其中的原理是什麼?可能還是有一些模糊隻知道這麼用。

說到java記憶體模型,它的設計的初衷就是為了定義程式中多線程通路時各個變量的通路規則。這裡的變量與java中變成所常說的這個變量是不一樣的,它隻包括了一些執行個體字段。比如一個類中的一個成員變量或者是靜态變量對吧?這些變量有一個共同的特征,就是屬于一個共享的資源,所有的線程都能夠去通路到的。

java常見面試題:聊聊你對java記憶體模型的看法 @抖音短視訊

這個資源它是不包括局部變量的。比如說在方法裡面去做一個變量的定義,這個變量是不屬于共享變量的,它是屬于線程私有的變量,不屬于Java記憶體模型考慮的範圍。

java常見面試題:聊聊你對java記憶體模型的看法 @抖音短視訊

Java記憶體模型中有兩個特别重要的概念,一個是主記憶體,一個是工作記憶體,它是不同于JVM堆記憶體的,屬于另外一個次元的劃分。主記憶體它是存儲所有的共享變量的,就是剛剛說的這個什麼類的成員或者靜态字段。這些被共享的字段是存儲在主記憶體中的,而每一個線程都有一個獨立于主記憶體的工作記憶體,就是每一個線程都有一個工作記憶體。

java常見面試題:聊聊你對java記憶體模型的看法 @抖音短視訊

工作記憶體除了自身的一些私有變量以外還會存儲共享記憶體的副本。比如靜态的字段所有的線程都會通路到。如果某一個線程用到了靜态字段,那麼線上程的工作記憶體中就會有一個靜态字段對應的副本。線程隻能操作自己的工作記憶體,不能夠直接操作主記憶體,這個是核心。如果線程在本地,它比如更新了某一個共享變量,某一個靜态字段。等到更新完成之後java記憶體模型就會自動的把更新後的值刷到主記憶體中,這個是記憶體模型的工作原理。

java常見面試題:聊聊你對java記憶體模型的看法 @抖音短視訊

但是在使用java記憶體模型的時候還是有幾點需要特别注意的,一個就是所謂的可見性的問題,就是線程在讀取共享變量的時候可能得到的是過期的值,因為這個值可能是在别的線程中被修改過了。

java常見面試題:聊聊你對java記憶體模型的看法 @抖音短視訊

這種情況如果是需要讓其他的線程能夠實時的去做一個更新,就需要在變量上面去加一個Volatile的修飾來保證它的可見性。

java常見面試題:聊聊你對java記憶體模型的看法 @抖音短視訊

·第二個是原子性的問題,比如多個線程對共享變量進行了非原子化的操作,就會導緻資料的不一緻的問題。比如i++就可能出現不一緻的問題,因為這是非原子化的操作,解決方案很簡單。常見的在它的參數上面去加一個syntronized修飾。

java常見面試題:聊聊你對java記憶體模型的看法 @抖音短視訊

·另外還有重排序的問題,簡單來講是它需要對某一個變量,它的執行順序做一個重排序以達到效率的最大化,但是這種情況可能會導緻資料不一緻的問題。同樣也是需要通過volatile或者syntronized來進行修飾。

本期的視訊就是這些了,如果您對本期的内容有任何疑問,歡迎大家在評論區給我留言,謝謝大家。