JVM學習筆記:Java內存模型面試題(JMM)

JVM學習筆記:Java內存模型(JMM)

前言:昨天看了《深入理解Java虛擬機》的第12章,想輸出一些內存複習一下Java的內存模型,持續輸出文檔吧,雖然技術性不是很強。

緩存一致性的問題,如何發生的?

計算機中多個處理器的運算任務都涉及同一塊主內存區域時,將可能導致各自的緩存數據不一致,引發緩存一致性的問題。

什麼是Java內存模型,你瞭解過Java內存模型嘛?

Java內存模型,規定所有的變量存儲在主內存中,每個線程還有自己的工作內存,線程的工作內存中保存了被該線程使用的變量的副本,線程對變量的所有操作(讀取、賦值等)都必須在工作內存中進行,而不能直接讀寫主內存中的數據。不同的線程之間也無法直接訪問對方工作內存中的變量,線程間變量值的傳遞均需要通過主內存來完成。

Java內存中的變量有哪些?

Java內存模型中的變量和Java編程中所說的變量有所區別,它包括了實例字段、靜態字段和構成數組對象的元素,不包括局部變量與方法參數。

volatile變量的兩個特性?

  1. 保證此變量對所有線程的可見性,這裏的“可見性”是指當一條線程修改了這個變量的值,新值對於其他線程來說是可以立即得知的。而普通變量並做不到這一點,普通變量的值在線程間傳遞時均需要通過主內存來完成。2. volatile 禁止指令重排序優化,避免指令重排序優化。

基於volatile變量的運算在併發下是線程安全的?

不一定,volatile變量在各個線程的工作內存是不存在內存一致性的問題,但是Java裏面的運算符並非原子操作,這導致volatile變量的運算在併發下一樣是不安全的。volatile關鍵字保證了值在當時是正確的,但是在進行運算的時候,其他的線程已經改變了它的值,這是他的值就過期了。

那種情況下可以使用volatile?

運算的結果不依賴變量的當前值,或者能夠確保只有單一的線程修改變量的值。變量不需要與其他的狀態變量共同參與不變約束。

變量被volatile修飾之後和普通變量會有怎麼的不同?

volatile修飾的變量賦值後,多執行了一個lock add 操作,他的作用相當於一個內存屏障,指令重排序不能把後面的指令重排序到內存屏障之前的位置。

變量被volatile修飾的特點?

  1. 每次使用volatile的值,都必須先從主內存刷新最新的值,用於保證能看見其他線程對volatile變量的修改
  2. 每次修改volatile的值,都必須立即同步到主內存中,用於保證其他的線程可以看到自己對volatile變量的修改
  3. volatile修飾的變量不會被指令重排序優化,從而保證代碼的執行順序與程序的順序相同。

Java內存模型的3個特性?

原子性、可見性與有序性

講一講原子性?

Java內存模型直接保證了原子性的操作有:read、load、assign、use、store、write,大致可以認爲,基本數據類型的訪問、讀寫都是具有原子性的(long和double除外)。如果需要更大範圍的原子性保證,Java內存模型提供了lock和unlock來滿足這種需求,Java提供更高層次的字節碼指令monitorenter和monitorexit來隱式的使用這兩個操作。這兩個字節碼指令反映到Java代碼中就是同步塊–synchronized關鍵字,因此synchronized塊之間的操作也具有原子性。

講一講可見性?

可見性就是指當一個線程修改了共享變量的值時,其他線程能夠立即得知這個修改。volatile的可見性的特殊規則保證了新值能立即同步到主內存,以及每次使用前立即從主內存刷新。

Java中保證可見性的有哪些?

除了volatile,還有synchronized和final。synchronized的可見性是對一個變量執行unlock操作之前,必須先把此變量同步回主內存中。final關鍵字的可見性是被final修飾的字段在構造器中一旦被初始化完成,那麼其他線程中就能看見final字段的值。

講一講有序性?

Java內存模型的有序性,如果在本線程內觀察,所有操作都是有序的;如果在一個線程中觀察另一個線程,所有操作都是無序的。Java語言提供了volatile和synchronized兩個關鍵字來保證線程之間操作的有序性,volatile關鍵字本身就包含了禁止指令重排序的語義,而synchronized則是一個變量在同一個時刻只允許一條線程對其進行lock操作。

什麼是happens-before原則?

happens-before原則是Java內存模型中定義的兩項操作之間的偏序關係,比如說操作A先行發生操作B,其實就是說在發生操作B之前,操作A產生的影響能被操作B觀察到。

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