那就要重提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)存中讀取共享變量,。 下面給大家分享一份成為資深架構(gòu)師學(xué)習(xí)路線 分布式專題 雙十一架構(gòu)專題 性能優(yōu)化專題 源碼分析專題 工程化專題 |
|