出處:http://www.cnblogs.com/dolphin0520/
Java內(nèi)存模型(Java Memory Model耻蛇,JMM)
內(nèi)存模型規(guī)定:
- 所有的變量都是存在主存當(dāng)中(類(lèi)似于物理內(nèi)存)
- 每個(gè)線程都有自己的工作內(nèi)存(類(lèi)似于高速緩存)
- 線程對(duì)變量的所有操作都必須在工作內(nèi)存中進(jìn)行笛钝,而不能直接對(duì)主存進(jìn)行操作月劈。
- 每個(gè)線程不能訪問(wèn)其他線程的工作內(nèi)存。
緩存一致性(Cache coherence)問(wèn)題
當(dāng)程序在運(yùn)行過(guò)程中阅畴,會(huì)將運(yùn)算需要的數(shù)據(jù)從主存復(fù)制一份到CPU的高速緩存當(dāng)中领斥,那么CPU進(jìn)行計(jì)算時(shí)就可以直接從它的高速緩存讀取數(shù)據(jù)和向其中寫(xiě)入數(shù)據(jù),當(dāng)運(yùn)算結(jié)束之后哩都,再將高速緩存中的數(shù)據(jù)刷新到主存當(dāng)中
在一個(gè)系統(tǒng)中,當(dāng)許多不同的設(shè)備共享一個(gè)共同存儲(chǔ)器資源婉徘,在高速緩存中的數(shù)據(jù)不一致漠嵌,就會(huì)產(chǎn)生問(wèn)題。也就是說(shuō)如果一個(gè)變量在多個(gè)CPU中都存在緩存(一般在多線程編程時(shí)才會(huì)出現(xiàn))盖呼,那么就可能存在緩存不一致的問(wèn)題儒鹿。
緩存一致性可以分為三個(gè)層級(jí):
- 在進(jìn)行每個(gè)寫(xiě)入運(yùn)算時(shí)都立刻采取措施保證數(shù)據(jù)一致性
- 每個(gè)獨(dú)立的運(yùn)算,假如它造成數(shù)據(jù)值的改變几晤,所有進(jìn)程都可以看到一致的改變結(jié)果
- 在每次運(yùn)算之后约炎,不同的進(jìn)程可能會(huì)看到不同的值(這也就是沒(méi)有一致性的行為)
為了解決緩存不一致性問(wèn)題,通常來(lái)說(shuō)有以下2種解決方法:
1.通過(guò)在總線加LOCK鎖的方式
2.通過(guò)緩存一致性協(xié)議蟹瘾。
最出名的就是Intel 的MESI協(xié)議圾浅,MESI協(xié)議保證了每個(gè)緩存中使用的共享變量的副本是一致的。
它核心的思想是:當(dāng)CPU寫(xiě)數(shù)據(jù)時(shí)憾朴,如果發(fā)現(xiàn)操作的變量是共享變量狸捕,即在其他CPU中也存在該變量的副本,會(huì)發(fā)出信號(hào)通知其他CPU將該變量的緩存行置為無(wú)效狀態(tài)众雷,因此當(dāng)其他CPU需要讀取這個(gè)變量時(shí)灸拍,發(fā)現(xiàn)自己緩存中緩存該變量的緩存行是無(wú)效的做祝,那么它就會(huì)從內(nèi)存重新讀取。
參考資料