描述下場景:一個main方法中有2個線程,initFlag是布爾類型的共享變量。一個線程是對initFlag作取反的死循環,一旦initFlag爲true就跳出死循環,執行打印success的操做;另外一個線程修改initFlag爲true,觸發第一個線程跳出死循環。第一個線程啓動以後sleep下確保在啓動第二個線程時第一個已經進入死循環。緩存
圖中有一個主內存區,2個線程,每一個線程有本身的工做內存,線程啓動以後會從主內存中讀取變量的副本存在工做內存中,經過read指令讀取、load指令載入工做內存。第二個線程會對initFlag取反操做,經過use指令讀取工做內存的變量,經過assign指令進行計算,把計算的新值賦值給工做內存的變量賦值。如果共享變量是volatile聲明的,就會把新值當即回寫到主內存,經過store指令讀取工做內存的變量傳入到主內存,而後在主內存中經過write指令給變量賦值。線程
回寫時底層經過lock前綴指令執行鎖定這塊內存區域的緩存(緩存行鎖定),而後執行store指令,這裏須要注意的是全部的讀寫請求都經過總線,由總線傳遞給全部的CPU。其餘CPU經過總線嗅探和緩存一致性協議來保證數據的一致性。具體是由每一個CPU經過總線嗅探機制會監聽本身工做內存中存在的變量,一旦發生回寫,緩存一致性協議會使得其餘CPU裏緩存了改內存地址的數據無效,當其餘CPU須要回寫或者使用時會從新從內存中讀取。在回寫到主內存完成以後會執行unlock指令,提供給其餘CPU使用。簡單的說就是全部的讀寫請求都經過總線傳遞給全部的CPU,而後CPU去「嗅探」這些請求,當感知到數據變化時將本身的緩存的數據置爲失效。blog