免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
Java內(nèi)存模型詳解

內(nèi)存模型 (memory model)

內(nèi)存模型描述的是程序中各變量(實例域、靜態(tài)域和數(shù)組元素)之間的關(guān)系,以及在實際計算機系統(tǒng)中將變量存儲到內(nèi)存和從內(nèi)存取出變量這樣的低層細節(jié).

不同平臺間的處理器架構(gòu)將直接影響內(nèi)存模型的結(jié)構(gòu).

在C或C++中, 可以利用不同操作平臺下的內(nèi)存模型來編寫并發(fā)程序. 但是, 這帶給開發(fā)人員的是, 更高的學習成本.相比之下,Java利用了自身虛擬機的優(yōu)勢, 使內(nèi)存模型不束縛于具體的處理器架構(gòu), 通過Java內(nèi)存模型真正實現(xiàn)了跨平臺.(針對hotspot jvm,jrockit等不同的jvm, 內(nèi)存模型也會不相同)

內(nèi)存模型的特征:

a, Visibility 可視性 (多核,多線程間數(shù)據(jù)的共享)

b, Ordering 有序性 (對內(nèi)存進行的操作應該是有序的)


Java內(nèi)存模型 ( java memory model )

根據(jù)Java Language Specification中的說明, jvm系統(tǒng)中存在一個主內(nèi)存(Main Memory或Java Heap Memory),Java中所有變量都儲存在主存中,對于所有線程都是共享的。

每條線程都有自己的工作內(nèi)存(Working Memory),工作內(nèi)存中保存的是主存中某些變量的拷貝,線程對所有變量的操作都是在工作內(nèi)存中進行,線程之間無法相互直接訪問,變量傳遞均需要通過主存完成。

其中, 工作內(nèi)存里的變量, 在多核處理器下, 將大部分儲存于處理器高速緩存中, 高速緩存在不經(jīng)過內(nèi)存時, 也是不可見的.

jmm怎么體現(xiàn)可視性(Visibility) ?

在jmm中, 通過并發(fā)線程修改變量值, 必須將線程變量同步回主存后, 其他線程才能訪問到.

jmm怎么體現(xiàn)有序性(Ordering) ?

通過Java提供的同步機制或volatile關(guān)鍵字, 來保證內(nèi)存的訪問順序.

緩存一致性(cache coherency

什么是緩存一致性?

它是一種管理多處理器系統(tǒng)的高速緩存區(qū)結(jié)構(gòu),其可以保證數(shù)據(jù)在高速緩存區(qū)到內(nèi)存的傳輸中不會丟失或重復。(來自wikipedia)

舉例理解:

假如有一個處理器有一個更新了的變量值位于其緩存中,但還沒有被寫入主內(nèi)存,這樣別的處理器就可能會看不到這個更新的值.

解決緩存一致性的方法?

a, 順序一致性模型:

要求某處理器對所改變的變量值立即進行傳播, 并確保該值被所有處理器接受后, 才能繼續(xù)執(zhí)行其他指令.

b, 釋放一致性模型: (類似jmm cache coherency)

允許處理器將改變的變量值延遲到釋放鎖時才進行傳播.

Java內(nèi)存模型的緩存一致性模型 - "happens-before ordering(先行發(fā)生排序)"

一般情況下的示例程序:

  1. x = 0;  
  2. y = 0;  
  3. i = 0;  
  4. j = 0;  
  5.  
  6. // thread A  
  7. y = 1;  
  8. x = 1;  
  9.  
  10. // thread B  
  11. i = x;  
  12. j = y; 

在如上程序中, 如果線程A,B在無保障情況下運行, 那么i,j各會是什么值呢?

答案是, 不確定. (00,01,10,11都有可能出現(xiàn)),這里沒有使用Java同步機制, 所以Java內(nèi)存模型有序性和可視性都無法得到保障. happens-before ordering( 先行發(fā)生排序) 如何避免這種情況? 排序原則已經(jīng)做到:

a, 在程序順序中, 線程中的每一個操作, 發(fā)生在當前操作后面將要出現(xiàn)的每一個操作之前.

b, 對象監(jiān)視器的解鎖發(fā)生在等待獲取對象鎖的線程之前.

c, 對volitile關(guān)鍵字修飾的變量寫入操作, 發(fā)生在對該變量的讀取之前.

d, 對一個線程的 Thread.start() 調(diào)用 發(fā)生在啟動的線程中的所有操作之前.

e, 線程中的所有操作 發(fā)生在從這個線程的 Thread.join()成功返回的所有其他線程之前.

為了實現(xiàn) happends-before ordering原則, Java及JDK提供的工具:

a, synchronized關(guān)鍵字

b, volatile關(guān)鍵字

c, final變量

d, java.util.concurrent.locks包(since jdk 1.5)

e, java.util.concurrent.atmoic包(since jdk 1.5)

使用了happens-before ordering的例子:

1) 獲取對象監(jiān)視器的鎖(lock)

(2) 清空工作內(nèi)存數(shù)據(jù), 從主存復制變量到當前工作內(nèi)存, 即同步數(shù)據(jù) (read and load)

(3) 執(zhí)行代碼,改變共享變量值 (use and assign)

(4) 將工作內(nèi)存數(shù)據(jù)刷回主存 (store and write)

(5) 釋放對象監(jiān)視器的鎖 (unlock)

注意: 其中4,5兩步是同時進行的.

這邊最核心的就是第二步, 他同步了主內(nèi)存,即前一個線程對變量改動的結(jié)果,可以被當前線程獲知!(利用了happens-before ordering原則)

對比之前的例子

如果多個線程同時執(zhí)行一段未經(jīng)鎖保護的代碼段,很有可能某條線程已經(jīng)改動了變量的值,但是其他線程卻無法看到這個改動,依然在舊的變量值上進行運算,最終導致不可預料的運算結(jié)果。

本站僅提供存儲服務,所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Java并發(fā)編程 (二) 并發(fā)基礎
Java內(nèi)存模型深度剖析
java并發(fā)編程學習1
Java并發(fā)編程:volatile關(guān)鍵字解析
JAVA內(nèi)存的可見性和指令的reorde
深入分析volatile的實現(xiàn)原理
更多類似文章 >>
生活服務
分享 收藏 導長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服