這篇文章主要介紹“Java內(nèi)存模型實例分析”的相關(guān)知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“Java內(nèi)存模型實例分析”文章能幫助大家解決問題。
創(chuàng)新互聯(lián)公司是一家專業(yè)提供回民企業(yè)網(wǎng)站建設(shè),專注與成都網(wǎng)站設(shè)計、成都網(wǎng)站建設(shè)、H5頁面制作、小程序制作等業(yè)務(wù)。10年已為回民眾多企業(yè)、政府機構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站制作公司優(yōu)惠進行中。
所有的編程語言中都有內(nèi)存模型這個概念,區(qū)別于微架構(gòu)的內(nèi)存模型,高級語言的內(nèi)存模型包括了編譯器和微架構(gòu)兩部分。我試圖了解了Java、C#和Go語言的內(nèi)存模型,發(fā)現(xiàn)內(nèi)容基本大同小異,只是這些語言在具體實現(xiàn)的時候略有不同。
我們來看看Java內(nèi)存模型吧,提到Java內(nèi)存模型大家對這個圖一定非常熟悉:
這張圖告訴我們在線程運行的時候有一個內(nèi)存專用的一小塊內(nèi)存,當(dāng)Java程序會將變量同步到線程所在的內(nèi)存,這時候會操作工作內(nèi)存中的變量,而線程 中變量的值何時同步回主內(nèi)存是不可預(yù)期的。但同時Java內(nèi)存模型又告訴我們通過使用關(guān)鍵詞“synchronized”或“volatile”可以讓 Java保證某些約束:
“volatile” — 保證讀寫的都是主內(nèi)存的變量
“synchronized” — 保證在塊開始時都同步主內(nèi)存的值到工作內(nèi)存,而塊結(jié)束時將變量同步回主內(nèi)存
通過以上描述我們就可以寫出線程安全的Java程序,JDK也同時幫我們屏蔽了很多底層的東西。
但當(dāng)你深入了解JVM的時候你會發(fā)現(xiàn)根本就沒有工作內(nèi)存這個東西,即內(nèi)存中根本不會分配這么一塊空間來運行你的Java程序,那么工作內(nèi)存到底是什么東西呢?
這個問題也曾經(jīng)困擾了我很長時間,因為我從來沒有從JVM的實現(xiàn)中找到過和主內(nèi)存同步的代碼,因為當(dāng)使用“volatile”時我僅僅能從源代碼中調(diào)用了這行語句:
__asm__ volatile ("lock; addl $0,0(%%esp)" : : : "cc", "memory");
而這個指令在部分微架構(gòu)上的主要功能就是防止指令重排,即這條指令前后的其它指令不會越過這個界限執(zhí)行[注1]。
在現(xiàn)在的x86/x64微架構(gòu)中讀寫內(nèi)存的一致性都是通過MESI(Intel使用MESI-F,AMD使用MOESI)協(xié)議保證[注2],MESI的狀態(tài)轉(zhuǎn)換圖如下:
那Java內(nèi)存模型中所說的工作內(nèi)存是什么呢?
我的理解是,首先“工作內(nèi)存”是一個虛擬的概念,而承載這個概念主要是兩部分:
1. 編譯器
2. 微架構(gòu)
作為編譯器肯定是執(zhí)行速度越快越好,所以作為編譯器應(yīng)當(dāng)盡量減少從內(nèi)存讀數(shù)據(jù),如果一個數(shù)據(jù)在寄存器中,那么直接使用寄存器中的值無疑性能是*** 的,但同時這也會導(dǎo)致可能讀不到***的值,這里我們通過在Java語言中為變量加上“volatile”強制告訴編譯器這個變量一定要從內(nèi)存獲得,這時編 譯器即不會做此類優(yōu)化【案例見參考資料5(是一個.Net的例子)】。
對于微架構(gòu)來說,在x86/x64下,CPU會在執(zhí)行指令時做指令重排,即編譯器生成的指令順序和真正在CPU執(zhí)行的順序可能是不一致的。當(dāng)我們用一個變量做信號的時候這種指令重排會帶來悲劇,即如果有如下代碼:
x = 0; y = 0; i = 0; j = 0; // thread A y = 1; x = 1; // thread B i = x; j = y;
上面的代碼i和j的值會是多少呢?答案是:“00, 01, 10, 11”都是有可能的。
對于這種情況,如果我們想得到確定的結(jié)果則需要通過“synchronized”(或者j.c.u.locks)來做線程間同步。
關(guān)于“Java內(nèi)存模型實例分析”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識,可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,小編每天都會為大家更新不同的知識點。