Java 內(nèi)存模型介紹

作用

JMM(Java Memory Model)是java內(nèi)存模型。用來屏蔽不同硬件不同操作系統(tǒng)訪問內(nèi)存的差異性,確保java程序在不同平臺上能達(dá)到一致的內(nèi)存訪問效果。也就是同一個程序在不同的虛擬機(jī)上運(yùn)行,得到的結(jié)果是一致的。

規(guī)范

在jmm規(guī)范中,所有的變量(不包括局部變量和方法參數(shù))都存儲在主內(nèi)存中,每個線程都有自己的工作內(nèi)存,工作內(nèi)存中的變量是主內(nèi)存該變量的拷貝。

線程不能直接讀寫主內(nèi)存,只能操作自己工作內(nèi)存中的變量,然后再同步到主內(nèi)存,這樣其它線程就能看到本次修改。

主內(nèi)存是多個線程共享的,工作內(nèi)存是線程私有的。線程間的通信必須通過主內(nèi)存來完成

JMM三大特性

  • 原子性:一個操作是不可分割,不可中斷的,一個線程在執(zhí)行時不會被其它線程干擾。java提供了synchronized關(guān)鍵字來保證原子性。

  • 可見性:一個線程修改共享變量的值,其它線程能夠立即知道。java是通過volatile關(guān)鍵字來提供可見性,另外final和synchronized關(guān)鍵字也能實現(xiàn)可見性。

  • 有序性:可以使用synchronized或者volatile關(guān)鍵字保證多線程之間操作的有序性。volatile是通過內(nèi)存屏障禁止指令重排序。synchronized代碼塊在多線程下是串行執(zhí)行。

JMM八種內(nèi)存操作

  • lock(鎖定):作用于主內(nèi)存中的變量,把變量標(biāo)識為線程獨占的狀態(tài)。
  • read(讀取):作用于主內(nèi)存的變量,把變量的值從主內(nèi)存?zhèn)鬏數(shù)骄€程的工作內(nèi)存中,以便下一步的load操作使用。
  • load(加載):作用于工作內(nèi)存的變量,把read操作主存的變量放入到工作內(nèi)存的變量副本中。
  • use(使用):作用于工作內(nèi)存的變量,把工作內(nèi)存中的變量傳輸?shù)綀?zhí)行引擎,每當(dāng)虛擬機(jī)遇到一個需要使用到變量的值的字節(jié)碼指令時將會執(zhí)行這個操作。
  • assign(賦值):作用于工作內(nèi)存的變量,它把一個從執(zhí)行引擎中接受到的值賦值給工作內(nèi)存的變量副本中,每當(dāng)虛擬機(jī)遇到一個給變量賦值的字節(jié)碼指令時將會執(zhí)行這個操作。
  • store(存儲):作用于工作內(nèi)存的變量,它把一個從工作內(nèi)存中一個變量的值傳送到主內(nèi)存中,以便后續(xù)的write使用。
  • write(寫入):作用于主內(nèi)存中的變量,它把store操作從工作內(nèi)存中得到的變量的值放入主內(nèi)存的變量中。
  • unlock(解鎖):作用于主內(nèi)存的變量,它把一個處于鎖定狀態(tài)的變量釋放出來,釋放后的變量才可以被其他線程鎖定。
    JMM八種內(nèi)存操作

happens-before原則

  • 程序次序規(guī)則:在一個線程中,按照代碼的順序,前面的操作Happens-Before于后面的任意操作。
  • volatile變量規(guī)則:對一個volatile變量的寫操作,Happens-Before于后續(xù)對這個變量的讀操作。
  • 傳遞規(guī)則:如果A Happens-Before B,并且B Happens-Before C,則A Happens-Before C。
  • 鎖定規(guī)則:對一個鎖的解鎖操作 Happens-Before于后續(xù)對這個鎖的加鎖操作。
  • 線程啟動規(guī)則:如果線程A調(diào)用線程B的start()方法來啟動線程B,則start()操作Happens-Before于線程B中的任意操作。
  • 線程終結(jié)規(guī)則:線程A等待線程B完成(在線程A中調(diào)用線程B的join()方法實現(xiàn)),當(dāng)線程B完成后(線程A調(diào)用線程B的join()方法返回),則線程A能夠訪問到線程B對共享變量的操作。
  • 線程中斷規(guī)則:對線程interrupt()方法的調(diào)用Happens-Before于被中斷線程的代碼檢測到中斷事件的發(fā)生。
  • 對象終結(jié)原則:一個對象的初始化完成Happens-Before于它的finalize()方法的開始。
?著作權(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)容

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