五月天青色头像情侣网名,国产亚洲av片在线观看18女人,黑人巨茎大战俄罗斯美女,扒下她的小内裤打屁股

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

深入淺出Java內(nèi)存模型

2023-06-07 21:24 作者:Java3y  | 我要投稿

面試官:我記得上一次已經(jīng)問過了為什么要有Java內(nèi)存模型

面試官:我記得你的最終答案是:Java為了屏蔽硬件和操作系統(tǒng)訪問內(nèi)存的各種差異,提出了「Java內(nèi)存模型」的規(guī)范,保證了Java程序在各種平臺(tái)下對(duì)內(nèi)存的訪問都能得到一致效果

候選者:嗯,對(duì)的

面試官要不,你今天再來講講Java內(nèi)存模型這里邊的內(nèi)容唄?

候選者:嗯,在講之前還是得強(qiáng)調(diào)下:Java內(nèi)存模型它是一種「規(guī)范」,Java虛擬機(jī)會(huì)實(shí)現(xiàn)這個(gè)規(guī)范。

候選者:Java內(nèi)存模型主要的內(nèi)容,我個(gè)人覺得有以下幾塊吧

候選者:1. Java內(nèi)存模型的抽象結(jié)構(gòu)

候選者:2. happen-before規(guī)則

候選者:3.對(duì)volatile內(nèi)存語義的探討(這塊我后面再好好解釋)


面試官那要不你就從第一點(diǎn)開始唄?先聊下Java內(nèi)存模型的抽象結(jié)構(gòu)?

候選者:嗯。Java內(nèi)存模型定義了:Java線程對(duì)內(nèi)存數(shù)據(jù)進(jìn)行交互的規(guī)范。

候選者:線程之間的「共享變量」存儲(chǔ)在「主內(nèi)存」中,每個(gè)線程都有自己私有的「本地內(nèi)存」,「本地內(nèi)存」存儲(chǔ)了該線程以讀/寫共享變量的副本。

候選者:本地內(nèi)存是Java內(nèi)存模型的抽象概念,并不是真實(shí)存在的。

候選者:順便畫個(gè)圖吧,看完圖就懂了。


候選者:Java內(nèi)存模型規(guī)定了:線程對(duì)變量的所有操作都必須在「本地內(nèi)存」進(jìn)行,「不能直接讀寫主內(nèi)存」的變量

候選者:Java內(nèi)存模型定義了8種操作來完成「變量如何從主內(nèi)存到本地內(nèi)存,以及變量如何從本地內(nèi)存到主內(nèi)存」

候選者:分別是read/load/use/assign/store/write/lock/unlock操作

候選者:看著8個(gè)操作很多,對(duì)變量的一次讀寫就涵蓋了這些操作了,我再畫個(gè)圖給你講講


候選者:懂了吧?無非就是讀寫用到了各個(gè)操作(:

面試官懂了,很簡(jiǎn)單,接下來說什么是happen-before吧?

候選者:嗯,好的(:

候選者:按我的理解下,happen-before實(shí)際上也是一套「規(guī)則」。Java內(nèi)存模型定義了這套規(guī)則,目的是為了闡述「操作之間」的內(nèi)存「可見性」

候選者:從上次講述「指令重排」就提到了,在CPU和編譯器層面上都有指令重排的問題。

候選者:指令重排雖然是能提高運(yùn)行的效率,但在并發(fā)編程中,我們?cè)诩骖櫋感省沟那疤嵯?,還希望「程序結(jié)果」能由我們掌控的。

候選者:說白了就是:在某些重要的場(chǎng)景下,這一組操作都不能進(jìn)行重排序,「前面一個(gè)操作的結(jié)果對(duì)后續(xù)操作必須是可見的」。


面試官:嗯…

候選者:于是,Java內(nèi)存模型就提出了happen-before這套規(guī)則,規(guī)則總共有8條

候選者:比如傳遞性、volatile變量規(guī)則、程序順序規(guī)則、監(jiān)視器鎖的規(guī)則…(具體看規(guī)則的含義就好了,這塊不難)

候選者:只要記住,有了happen-before這些規(guī)則。我們寫的代碼只要在這些規(guī)則下,前一個(gè)操作的結(jié)果對(duì)后續(xù)操作是可見的,是不會(huì)發(fā)生重排序的。

面試官:我明白你的意思了

面試官那最后說下volatile?

候選者:嗯,volatile是Java的一個(gè)關(guān)鍵字

候選者:為什么講Java內(nèi)存模型往往就會(huì)講到volatile這個(gè)關(guān)鍵字呢,我覺得主要是它的特性:可見性和有序性(禁止重排序)

候選者:Java內(nèi)存模型這個(gè)規(guī)范,很大程度下就是為了解決可見性和有序性的問題。


面試官那你來講講它的原理吧,volatile這個(gè)關(guān)鍵字是怎么做到可見性和有序性的

候選者:Java內(nèi)存模型為了實(shí)現(xiàn)volatile有序性和可見性,定義了4種內(nèi)存屏障的「規(guī)范」,分別是LoadLoad/LoadStore/StoreLoad/StoreStore

候選者:回到volatile上,說白了,就是在volatile「前后」加上「內(nèi)存屏障」,使得編譯器和CPU無法進(jìn)行重排序,致使有序,并且寫volatile變量對(duì)其他線程可見。

候選者:Java內(nèi)存模型定義了規(guī)范,那Java虛擬機(jī)就得實(shí)現(xiàn)啊,是不是?

面試官:嗯…

候選者:之前看過Hotspot虛擬機(jī)的實(shí)現(xiàn),在「匯編」層面上實(shí)際是通過Lock前綴指令來實(shí)現(xiàn)的,而不是各種fence指令(主要原因就是簡(jiǎn)便。因?yàn)榇蟛糠制脚_(tái)都支持lock指令,而fence指令是x86平臺(tái)的)。

候選者:lock指令能保證:禁止CPU和編譯器的重排序(保證了有序性)、保證CPU寫核心的指令可以立即生效且其他核心的緩存數(shù)據(jù)失效(保證了可見性)。


面試官那你提到這了,我想問問volatile和MESI協(xié)議是啥關(guān)系?

候選者:它們沒有直接的關(guān)聯(lián)。

候選者:Java內(nèi)存模型關(guān)注的是編程語言層面上,它是高維度的抽象。MESI是CPU緩存一致性協(xié)議,不同的CPU架構(gòu)都不一樣,可能有的CPU壓根就沒用MESI協(xié)議…

候選者:只不過MESI名聲大,大家就都拿他來舉例子了。而MESI可能只是在「特定的場(chǎng)景下」為實(shí)現(xiàn)volatile的可見性/有序性而使用到的一部分罷了(:

面試官:嗯…

候選者:為了讓Java程序員屏蔽上面這些底層知識(shí),快速地入門使用volatile變量

候選者:Java內(nèi)存模型的happen-before規(guī)則中就有對(duì)volatile變量規(guī)則的定義

候選者:這條規(guī)則的內(nèi)容其實(shí)就是:對(duì)一個(gè) volatile 變量的寫操作相對(duì)于后續(xù)對(duì)這個(gè) volatile 變量的讀操作可見

候選者:它通過happen-before規(guī)則來規(guī)定:只要變量聲明了volatile 關(guān)鍵字,寫后再讀,讀必須可見寫的值。(可見性、有序性)

面試官:嗯…了解了

本文總結(jié)

  • 為什么存在Java內(nèi)存模型:Java為了屏蔽硬件和操作系統(tǒng)訪問內(nèi)存的各種差異,提出了「Java內(nèi)存模型」的規(guī)范,保證了Java程序在各種平臺(tái)下對(duì)內(nèi)存的訪問都能得到一致效果
  • Java內(nèi)存模型抽象結(jié)構(gòu):線程之間的「共享變量」存儲(chǔ)在「主內(nèi)存」中,每個(gè)線程都有自己私有的「本地內(nèi)存」,「本地內(nèi)存」存儲(chǔ)了該線程以讀/寫共享變量的副本。線程對(duì)變量的所有操作都必須在「本地內(nèi)存」進(jìn)行,而「不能直接讀寫主內(nèi)存」的變量
  • happen-before規(guī)則:Java內(nèi)存模型規(guī)定在某些場(chǎng)景下(一共8條),前面一個(gè)操作的結(jié)果對(duì)后續(xù)操作必須是可見的。這8條規(guī)則成為happen-before規(guī)則
  • volatile:volatile是Java的關(guān)鍵字,修飾的變量是可見性且有序的(不會(huì)被重排序)??梢娦杂蒱appen-before規(guī)則完成,有序性由Java內(nèi)存模型定義的「內(nèi)存屏障」完成,實(shí)際HotSpot虛擬機(jī)實(shí)現(xiàn)Java內(nèi)存模型規(guī)范,匯編底層通過Lock指令來實(shí)現(xiàn)。

對(duì)線面試官PDF版本,可+V: java3yyy 免費(fèi)領(lǐng)取

深入淺出Java內(nèi)存模型的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國家法律
都江堰市| 宽城| 罗定市| 浮山县| 平陆县| 信宜市| 汨罗市| 河北省| 古蔺县| 曲水县| 永泰县| 同心县| 内江市| 收藏| 长岛县| 五指山市| 秦安县| 河北省| 宁河县| 博乐市| 贵南县| 涿州市| 翼城县| 章丘市| 莆田市| 石泉县| 南开区| 泗阳县| 铁岭市| 兴化市| 清丰县| 塘沽区| 揭西县| 尤溪县| 凭祥市| 淳安县| 容城县| 拉萨市| 凤凰县| 涞水县| 精河县|