通過 JVM (HotSpot) 源碼和匯編理解 Java volatile 實(shí)現(xiàn)原理

了解 volatile 前請先了解 「Java 內(nèi)存模型 (JMM)」是什么

一. volatile 作用是什么

  • 保證變量在多線程之間的可見性

  • 防止重排序

    • 編譯器重排序
    • 指令級重排序
    • 內(nèi)存重排序

二. 多線程之間的內(nèi)存可見性是什么,如果不保證可見性會怎么樣

如果不保證可見性的話,比如下面這段代碼, 當(dāng)變量 asscse 被改變?yōu)?1 后,開啟的 thread 并不會結(jié)束運(yùn)行,因?yàn)?asscse 被拷貝到了線程的工作內(nèi)存中(以 server 模式運(yùn)行)

image.png

三. 通過 JVM 源碼和匯編看怎么保證的多線程間的可見性

1. 準(zhǔn)備工作:

運(yùn)行程序打印匯編代碼的設(shè)置
image.png

2. 字節(jié)碼

帶 volatile 關(guān)鍵詞時,多了一個 ACC_VOLATILE

image.png

3. JVM 源碼

通過 ACC_VOLATILE 看下 JVM 做了啥, 搜索 hotspot 源碼,看到了兩處 is_volatile

image.png

繼續(xù)搜索is_volatile 做了什么,我靠這也太多了,160 + 結(jié)果,作為 Java 入道程序員,這個 C++ 看著確實(shí)有點(diǎn)拙計,得想點(diǎn)別的辦法。。

image.png

4. 反編譯為匯編(不帶 volatile 關(guān)鍵詞)

我想看看反匯編出來的代碼在使用和未使用 volatile 關(guān)鍵詞修飾時的差異


image.png

5. 反編譯為匯編(帶 volatile 關(guān)鍵詞)

可以看出相對于不帶 volatile 關(guān)鍵字是多了一行 lock addl $0x0,(%rsp),開心。。

image.png

6. JVM 源碼

根據(jù) lock addl 搜索到了兩個結(jié)果,哈哈,看到了 '順序存取' ,打開 orderAccess.hpp 看一下


image.png

下面這張圖中看到了,一大篇注釋,在是解釋內(nèi)存模型 (JSR-133)和他們處理內(nèi)存模型的方法其中包含 lock addl 對應(yīng)的 fence 和其他函數(shù),感興趣的可以更具體的閱讀:JDK8 hotspot - orderAccess.hpp 源碼

image.png

找到 orderAccess.hpp 的實(shí)現(xiàn),可以看到 fence 函數(shù)中,內(nèi)嵌了匯編,寫入了 lock addl $0x0,(%rsp)


image.png

6. lock addl $0x0,(%rsp) 是什么

IA32 中對 lock 的說明是

The LOCK # signal is asserted during execution of the instruction following the lock prefix. This signal can be used in a multiprocessor system to ensure exclusive use of shared memory while LOCK # is asserted

LOCK 用于在多處理器中執(zhí)行指令時對共享內(nèi)存的獨(dú)占使用。它的作用是能夠?qū)?dāng)前處理器對應(yīng)緩存的內(nèi)容刷新到內(nèi)存,并使其他處理器對應(yīng)的緩存失效。另外還提供了有序的指令無法越過這個內(nèi)存屏障的作用。

正是 lock 實(shí)現(xiàn)了 volatile 的「防止指令重排」「內(nèi)存可見」的特性

五. 參考

查看Java的匯編指令Java 內(nèi)存模型
從 HotSpot 源碼看 Java volatile
就是要你懂 Java 中 volatile 關(guān)鍵字實(shí)現(xiàn)原理
volatile在java server模式和client模式下的不同(主內(nèi)存和工作內(nèi)存)
Java并發(fā)編程 - volatile

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容