知道這些,面試時volatile就穩了

在Java相關的崗位面試中,不少面試官都喜歡考察面試者對Java併發的瞭解程度,而以volatile關鍵字做爲一個小的切入點,每每能夠一問到底,把Java內存模型(JMM),Java併發編程的一些特性都牽扯出來,深刻地話還能夠考察JVM底層實現以及操做系統的相關知識。
本文以一次假想的面試過程,來深刻了解下volitile關鍵字
題目有標題黨的嫌疑,可是若是你們好好理解文中涉及到的兩篇文章,相信你對volatile有更深入的認識!

【靈魂拷問開始】

面試官:Java併發這塊瞭解的怎麼樣?說說你對volatile關鍵字的理解?
面試官:能不能詳細說下什麼是內存可見性,什麼又是重排序呢?
面試官:volatile怎麼保證可見性的?多個線程之間的可見性,你能講一下底層原理是怎麼實現的嗎?
面試官:volatile關鍵字是怎麼保證有序性的?
面試官:volatile能保證可見性和有序性,可是能保證原子性嗎?爲何?
面試官:瞭解過JMM內存模型嗎?簡單的講講
到這裏,個人眼裏已經是常含淚水了。不是由於我對代碼愛的深沉,而是由於我菜的真誠!面試

沒事,不就是個破volatile嗎?別念了,我學習還不行嗎!編程

Q1:請你談談對volatile關鍵字的理解?

volatile是JVM提供的輕量級的同步機制緩存

1.保證可見性
2.保證有序性,禁止指令重排
3.不保證原子性(須要藉助synchronized或者CAS)併發

小夥子,不錯麼😊,回答對了 1 + 1,得來點 2 + 2 的難度了app

Q2:什麼是內存可見性,volatile怎麼保證多個線程之間的可見性的?

問題2和問題3講到的可見性,用JMM來解釋的話,本質上是同一個問題。至於有序性和重排序,到問題4再討論。學習

一問到內存的可見性,volatile相關的,直接就把JMM內存模型搬出來好吧。先放圖,而後再表演。spa

如下是俺我的的回答,有不足或漏洞,歡迎你們更正指出!操作系統

所謂可見性,是指當一條線程修改了共享變量的值,新值對於其餘線程來講是能夠當即得知的

每一個線程都有本身獨立的工做區間,爲了匹配CPU的運行速度,他們不會直接從內存中讀取數據,而是將數據拷貝一份到CPU緩存中(即每一個線程本身的工做內存),他們之間的相互交互,是經過內存來完成的。線程

根據JMM內存模型的8大原子操做,每一個線程在j將數據操做完stroe回主存以前,會加lock指令來鎖定內存區域的緩存(緩存行鎖定),根據MESI緩存一致性協議,總線經過偵聽器發現數據被修改,會當即讓其餘線程工做內存中不一致的副本當即失效。3d

等到當前線程將更改後的數據write回主存後,當即執行unlock指令。

此時,其餘線程再從新讀取更新後的數據,再拷貝到本身的工做內存。總線偵聽機制會在總線上檢測線程的數據,發現有線程作了更改時準備store回主內存時,它就會馬上將其餘線程工做內存中的副本置位無效,而後重新到主存獲取更新後的值。

除了使用 volatile 關鍵字來保證內存可見性以外,使用synchronized或Lock鎖也能保證變量的內存可見性。只是相比而言使用 volatile關鍵字開銷更小,是輕量級的鎖。

這就是內存可見性的原理。

Q3:volatile關鍵字是怎麼保證有序性的?

使用volatile關鍵字修飾共享變量即可以禁止指令重排序。若用volatile修飾共享變量,在JVM底層volatile是採用「內存屏障」來實現禁止特定類型的處理器重排序。加入volatile關鍵字時,會多出一個lock前綴指令,lock前綴指令實際上至關於一個內存屏障(也成內存柵欄),內存屏障會提供3個功能:

1.它確保指令重排序時不會把其後面的指令排到內存屏障以前的位置,也不會把前面的指令排到內存屏障的後面;即在執行到內存屏障這句指令時,在它前面的操做已經所有完成;

2.它會強制將對緩存的修改操做當即寫入主存;

3.若是是寫操做,它會致使其餘CPU中對應的緩存行無效。

JMM具有一些先天的有序性,經過Happens-Before原則就能夠保證的必定的有序性。

Q4:volatile能保證可見性和有序性,可是能保證原子性嗎?爲何?

volatile關鍵字不能保證原子性。

a. 當寫一個volatile變量時,JMM會把該線程本地內存中的變量強制刷新到主內存中去;

b. 這個寫會操做會致使其餘線程中的緩存無效。

對於相似i++這樣的複合操做,要想保證原子性,只能藉助於synchronized、Lock以及併發包下的AtomicInteger的原子操做類。AtomicInteger對基本數據類型的 自增(加1操做),自減(減1操做)、以及加法操做(加一個數),減法操做(減一個數)進行了封裝,保證這些操做是原子性操做。

Q5:瞭解過JMM內存模型嗎?簡單的講講

看着這張圖,直接就巴拉巴拉一頓操做!

相關文章
相關標籤/搜索