volatile原理知道嗎?

相?synchronized的加鎖?式來解決共享變量的內(nèi)存可?性問題,volatile就是更輕量的選擇,他沒有上

下?切換的額外開銷成本。使?volatile聲明的變量,可以確保值被更新的時候?qū)ζ渌€程?刻可?。

volatile使?內(nèi)存屏障來保證不會發(fā)?指令重排,解決了內(nèi)存可?性的問題。

我們知道,線程都是從主內(nèi)存中讀取共享變量到?作內(nèi)存來操作,完成之后再把結(jié)果寫會主內(nèi)存,但是

這樣就會帶來可?性問題。舉個例?,假設(shè)現(xiàn)在我們是兩級緩存的雙核CPU架構(gòu),包含L1、L2兩級緩

存。

1. 線程A?先獲取變量X的值,由于最初兩級緩存都是空,所以直接從主內(nèi)存中讀取X,假設(shè)X初始值為

0,線程A讀取之后把X值都修改為1,同時寫回主內(nèi)存。這時候緩存和主內(nèi)存的情況如下圖。

線程A讀取數(shù)據(jù)

2. 線程B也同樣讀取變量X的值,由于L2緩存已經(jīng)有緩存X=1,所以直接從L2緩存讀取,之后線程B把X

修改為2,同時寫回L2和主內(nèi)存。這時候的X值?下圖所示。

那么線程A如果再想獲取變量X的值,因為L1緩存已經(jīng)有x=1了,所以這時候變量內(nèi)存不可?問題就

產(chǎn)?了,B修改為2的值對A來說沒有感知。

線程B讀取數(shù)

那么,如果X變量?volatile修飾的話,當(dāng)線程A再次讀取變量X的話,CPU就會根據(jù)緩存?致性協(xié)議強制

線程A重新從主內(nèi)存加載最新的值到??的?作內(nèi)存,?不是直接?緩存中的值。

再來說內(nèi)存屏障的問題,volatile修飾之后會加?不同的內(nèi)存屏障來保證可?性的問題能正確執(zhí)?。這?

寫的屏障基于書中提供的內(nèi)容,但是實際上由于CPU架構(gòu)不同,重排序的策略不同,提供的內(nèi)存屏障也

不?樣,?如x86平臺上,只有StoreLoad?種內(nèi)存屏障。

1. StoreStore屏障,保證上?的普通寫不和volatile寫發(fā)?重排序

2. StoreLoad屏障,保證volatile寫與后?可能的volatile讀寫不發(fā)?重排序

3. LoadLoad屏障,禁?volatile讀與后?的普通讀重排序

4. LoadStore屏障,禁?volatile讀和后?的普通寫重排序

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容