volatile關(guān)鍵字如何滿足并發(fā)編程的三大特性的?

那就要重提volatile變量規(guī)則: 對一個volatile域的寫,happens-before于后續(xù)對這個volatile域的讀。 這條再拎出來說,其實就是如果一個變量聲明成是volatile的,那么當(dāng)我讀變量時,總是能讀到它的最新值,這里最新值是指不管其它哪個線程對該變量做了寫操作,都會立刻被更新到主存里,我也能從主存里讀到這個剛寫入的值。也就是說volatile關(guān)鍵字可以保證可見性以及有序性。

繼續(xù)拿上面的一段代碼舉例:

這段代碼不僅僅受到重排序的困擾,即使1、2沒有重排序。3也不會那么順利的執(zhí)行的。假設(shè)還是線程1先執(zhí)行write操作,線程2再執(zhí)行multiply操作,由于線程1是在工作內(nèi)存里把flag賦值為1,不一定立刻寫回主存,所以線程2執(zhí)行時,multiply再從主存讀flag值,仍然可能為false,那么括號里的語句將不會執(zhí)行。

如果改成下面這樣:


那么線程1先執(zhí)行write,線程2再執(zhí)行multiply。根據(jù)happens-before原則,這個過程會滿足以下3類規(guī)則:

程序順序規(guī)則:1 happens-before 2; 3 happens-before 4; (volatile限制了指令重排序,所以1 在2 之前執(zhí)行)

volatile規(guī)則:2 happens-before 3

傳遞性規(guī)則:1 happens-before 4

從內(nèi)存語義上來看

當(dāng)寫一個volatile變量時,JMM會把該線程對應(yīng)的本地內(nèi)存中的共享變量刷新到主內(nèi)存

當(dāng)讀一個volatile變量時,JMM會把該線程對應(yīng)的本地內(nèi)存置為無效,線程接下來將從主內(nèi)存中讀取共享變量。

?著作權(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)容

  • 在Java相關(guān)的崗位面試中,很多面試官都喜歡考察面試者對Java并發(fā)的了解程度,而以volatile關(guān)鍵字作為一個...
    卡巴拉的樹閱讀 2,911評論 1 26
  • layout: posttitle: 《Java并發(fā)編程的藝術(shù)》筆記categories: Javaexcerpt...
    xiaogmail閱讀 6,005評論 1 19
  • 有人問:這傻妮子從哪來? 有人答:許是從天上來。 那人又問:孫悟空還從石頭縫里蹦出來的呢…… 其實,傻妮子沒有了爹...
    郝逗閱讀 1,241評論 0 1
  • 你要多努力,才能對得起你所吃過的苦!
    楓楓的小晴天閱讀 77評論 0 0
  • 這是我回到工作地方的第二個禮拜,十四天窩在出租屋里除了睡覺就是看綜藝娛樂。這期間大大小小的公司聯(lián)系了16家,面試了...
    summer_204c閱讀 244評論 0 0

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