Volatile缓存可见性实现原理(JMM数据原子操作具体步骤)
Java內(nèi)存模型:
JMM數(shù)據(jù)原子操作:
具體操作步驟:
線程1:先把initFlag變量read讀取出來(lái),再load載入工作內(nèi)存,use使用線程1執(zhí)行代碼!initFlag
線程2:先把initFlag變量read讀取出來(lái),再load載入工作內(nèi)存,use使用線程2執(zhí)行代碼initFlag=true,再assign重新賦值,store存儲(chǔ)并寫入主內(nèi)存,write寫入到主內(nèi)存中的變量。(線程2對(duì)緩存行l(wèi)ock加鎖,write寫入主內(nèi)存后會(huì)解鎖unlock,防止initFlag還未write寫入主內(nèi)存就被線程1讀取為false)。
線程1:因?yàn)閕nitFlag被volatile修飾,使用MESI緩存一致性協(xié)議,線程1cpu總線嗅探機(jī)制監(jiān)聽到了initFlag值的修改,線程1中initFlag=false失效變?yōu)閠rue退出循環(huán)繼續(xù)執(zhí)行,體現(xiàn)了多線程同步運(yùn)行共享變量副本的可見性。如果initFlag沒(méi)有被volatile修飾,線程1將感知不到initFlag的變化,一直循環(huán)下去停止不了。
圖中的代碼:
public class VolatileVisibilityTest {//volatile變量,用來(lái)確保將變量的更新操作通知到其他線程。private static volatile boolean initFlag = false;public static void main(String[] args) throws InterruptedException {new Thread(new Runnable() {@Overridepublic void run() {System.out.println("waiting data...");while (!initFlag) {}System.out.println("==============success");}}).start();Thread.sleep(2000);new Thread(new Runnable() {@Overridepublic void run() {prepareData();}}).start();}public static void prepareData(){System.out.println("preparing data...");initFlag = true;System.out.println("prepare data end...");} }解決jmm緩存不一致問(wèn)題:
總線加鎖:
lock和unlock會(huì)對(duì)主內(nèi)存加鎖的,總線加鎖一般不使用,效率太低,跟單線程差不多。一般用MESI緩存一致性協(xié)議。
總結(jié)
以上是生活随笔為你收集整理的Volatile缓存可见性实现原理(JMM数据原子操作具体步骤)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: MySQL性能优化步骤
- 下一篇: hashmap的各种问题及答案