那就要重提volatile變量規(guī)則: 對(duì)一個(gè)volatile域的寫(xiě)玖像,happens-before于后續(xù)對(duì)這個(gè)volatile域的讀。 這條再拎出來(lái)說(shuō),其實(shí)就是如果一個(gè)變量聲明成是volatile的捐寥,那么當(dāng)我讀變量時(shí)笤昨,總是能讀到它的最新值,這里最新值是指不管其它哪個(gè)線程對(duì)該變量做了寫(xiě)操作握恳,都會(huì)立刻被更新到主存里瞒窒,我也能從主存里讀到這個(gè)剛寫(xiě)入的值。也就是說(shuō)volatile關(guān)鍵字可以保證可見(jiàn)性以及有序性乡洼。
繼續(xù)拿上面的一段代碼舉例:
這段代碼不僅僅受到重排序的困擾崇裁,即使1、2沒(méi)有重排序束昵。3也不會(huì)那么順利的執(zhí)行的拔稳。假設(shè)還是線程1先執(zhí)行write操作,線程2再執(zhí)行multiply操作锹雏,由于線程1是在工作內(nèi)存里把flag賦值為1巴比,不一定立刻寫(xiě)回主存,所以線程2執(zhí)行時(shí)礁遵,multiply再?gòu)闹鞔孀xflag值轻绞,仍然可能為false,那么括號(hào)里的語(yǔ)句將不會(huì)執(zhí)行佣耐。
如果改成下面這樣:
那么線程1先執(zhí)行write,線程2再執(zhí)行multiply铲球。根據(jù)happens-before原則,這個(gè)過(guò)程會(huì)滿足以下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)存語(yǔ)義上來(lái)看
當(dāng)寫(xiě)一個(gè)volatile變量時(shí)稼病,JMM會(huì)把該線程對(duì)應(yīng)的本地內(nèi)存中的共享變量刷新到主內(nèi)存
當(dāng)讀一個(gè)volatile變量時(shí),JMM會(huì)把該線程對(duì)應(yīng)的本地內(nèi)存置為無(wú)效掖鱼,線程接下來(lái)將從主內(nèi)存中讀取共享變量然走。