JMM筆記

先分析下線程訪問(wèn)數(shù)據(jù)的上述圖結(jié)構(gòu)

共享數(shù)據(jù)存儲(chǔ)在主內(nèi)存中,每個(gè)線程訪問(wèn)數(shù)據(jù)先把共享數(shù)據(jù)拷貝一份到各自線程的本地內(nèi)存中,線程運(yùn)行的數(shù)據(jù)其實(shí)是本地內(nèi)存中的拷貝數(shù)據(jù)。線程A對(duì)共享變量做出改變后,刷新到本地內(nèi)存,然后在某個(gè)時(shí)刻再刷新到主內(nèi)存(不是立即刷)。線程B再去訪問(wèn)該共享變量,從主內(nèi)存讀取副本到B的本地內(nèi)存。多線程通過(guò)主內(nèi)存共享變量的方式來(lái)達(dá)到數(shù)據(jù)通信。

本地內(nèi)存

本地內(nèi)存只是一個(gè)概念性的東西,實(shí)際并不存在,例如CPU高速緩存,讀寫(xiě)緩存器,寄存器,及其他硬件都屬于本地內(nèi)存的范疇

從原子性、可見(jiàn)性、有序性方面分析JMM

原子性

原子性要求同時(shí)只有一個(gè)線程操作代碼,不允許打斷,要不執(zhí)行完全,要不就不執(zhí)行。

可以通過(guò)synchronized和lock來(lái)解決

可見(jiàn)性

可見(jiàn)性即內(nèi)存可見(jiàn)。在分析上述圖片流程時(shí),線程A修改數(shù)據(jù)后,沒(méi)有立即刷新到主內(nèi)存,B線程如果在A中共享變量刷新到主內(nèi)存前去讀取,得到的數(shù)據(jù)就不是最新的。這就是可見(jiàn)性問(wèn)題??梢酝ㄟ^(guò)同步或者volatile解決

有序性

java編譯器或者處理器會(huì)對(duì)指令重排,單線程模式下處理器會(huì)保持執(zhí)行結(jié)果的一致性。例如:

class A {}

A a = new A();

創(chuàng)建對(duì)象這一步不是原子性操作,是一個(gè)復(fù)合操作:

1:collect申請(qǐng)內(nèi)存

2:完成對(duì)象初始化

3:將對(duì)象堆內(nèi)存首地址賦值給a

這三個(gè)指令在運(yùn)行時(shí)順序是不可控的。這就是在創(chuàng)建單例時(shí)要加volatile的原因,禁止指令重排。

volatile

1:對(duì)基本類(lèi)型成員變量的度和寫(xiě)操作(不是復(fù)合操作)保持原子性

2:保持?jǐn)?shù)據(jù)在線程間的可見(jiàn)性

3:在一定程度上保持有序性。主要是通過(guò)禁止指令重排來(lái)達(dá)到的。之所以說(shuō)一定程度上保持,是因?yàn)椴荒芡耆3?,禁止指令重排volatile對(duì)讀和寫(xiě)限制是不一樣的。

int i; ????????????????????????// 1

int j;???????????? ????????????// 2

int value = i + j;? ? ? ?// 3

volatile x = 2;? ? ? ? ? // 4

int max = x;? ? ? ? ? ? // 5

int index = i;? ? ? ? ? ?// 6

1)第4處是volatile的寫(xiě)操作。volatile的寫(xiě)操作與它之前的讀寫(xiě)操作是禁止重排序的,也就是說(shuō)1,2,3要發(fā)生在4執(zhí)行之前完全執(zhí)行完畢,并且對(duì)volatile及之后的指令具有可見(jiàn)性,但是6的有序性不能保證,6有可能在1或2后面。根據(jù)happen-befores原則,6一定在1后面。

2)第5處是對(duì)volatile的讀操作。volatile讀操作與它之后的讀寫(xiě)操作是禁止重排序的,也就是說(shuō)6要發(fā)生在5之后執(zhí)行。

此處是volatile寫(xiě)操作,因此就可以保證對(duì)象創(chuàng)建完全才會(huì)發(fā)生賦值操作,就避免了問(wèn)題。

這里有java內(nèi)存模型的系列文章,非常詳細(xì):

https://www.infoq.cn/article/java-memory-model-1

https://www.infoq.cn/article/java-memory-model-2

https://www.infoq.cn/article/java-memory-model-3

https://www.infoq.cn/article/java-memory-model-4

https://www.infoq.cn/article/java-memory-model-5

https://www.infoq.cn/article/java-memory-model-6

https://www.infoq.cn/article/java-memory-model-7

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

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