亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

JVM并發機制探討—內存模型、內存可見性和指令重排序

2019-11-11 04:54:14
字體:
來源:轉載
供稿:網友

并發本來就是個有意思的問題,尤其是現在又流行這么一句話:“高帥富加機器,窮矮搓搞優化”。從這句話可以看到,無論是高帥富還是窮矮搓都需要深入理解并發編程,高帥富加多了機器,需要協調多臺機器或者多個CPU對共享資源的訪問,因此需要了解并發,窮矮搓搞優化需要編寫各種多線程的代碼來壓榨 CPU的計算資源,讓它在同一時刻做更多的事情,這個更需要了解并發。

在我前一篇關于并發的文章http://my.oschina.NET/chihz/blog/54731中提到過管程,管程的特色是在編程語言中 對并發的細節進行封裝,使程序員可以直接在語言中就得到并發的支持,而不必自己去處理一些像是控制信號量之類容易出錯且繁瑣的細節問題。一些語言是通過在 編譯時解開語法糖的方式去實現管程,但java在編譯后生成的字節碼層面上對并發仍然是一層封裝,比如syncrhonized塊在編譯之后只是對應了兩 條指令:monitorenter和monitorexit。更多的并發細節是在JVM運行時去處理的,而不是編譯。這篇文章主要是針對JVM處理并發的 一些細節的探討。

JAVA內存模型

對于我們平時開發的業務應用來說,內存應該是訪問速度最快的存儲設備,對于頻繁訪問的數據,我們總是習慣把它們放到內存緩存中,有句話不是說么,緩 存就像是清涼油,哪里有問題就抹一抹。但是CPU的運算速度比起內存的訪問速度還要快幾個量級,為了平衡這個差距,于是就專門為CPU引入了高速緩存,頻 繁使用的數據放到高速緩存當中,CPU在使用這些數據進行運算的時候就不必再去訪問內存。但是在多CPU時代卻有一個問題,每個CPU都擁有自己的高速緩 存,內存又是所有CPU共享的公共資源,于是內存此時就成了一個臨界區,如果控制不好各個CPU對內存的并發訪問,那么就會產生錯誤,出現數據不一致的情 況。為了避免這種情況,需要采取緩存一致性協議來保證,這類協議有很多,各個硬件平臺和操作系統的實現不盡相同。

JVM需要實現跨平臺的支持,它需要有一套自己的同步協議來屏蔽掉各種底層硬件和操作系統的不同,因此就引入了Java內存模型。對于Java來說 開發者并不需要關心任何硬件細節,因此沒有多核CPU和高速緩存的概念,多核CPU和高速緩存在JVM中對應的是Java語言內置的線程和每個線程所擁有 的獨立內存空間,Java內存模型所規范的也就是數據在線程自己的獨立內存空間和JVM共享內存之間同步的問題。下面這兩張圖說明了硬件平臺和JVM內存 模型的相似和差異之處。

CPU緩存和內存模型

JVM線程內存模型

Java內存模型規定,對于多個線程共享的變量,存儲在主內存當中,每個線程都有自己獨立的工作內存,線程只能訪問自己的工作內存,不可以訪問其它 線程的工作內存。工作內存中保存了主內存共享變量的副本,線程要操作這些共享變量,只能通過操作工作內存中的副本來實現,操作完畢之后再同步回到主內存當 中。如何保證多個線程操作主內存的數據完整性是一個難題,Java內存模型也規定了工作內存與主內存之間交互的協議,首先是定義了8種原子操作:

(1) lock:將主內存中的變量鎖定,為一個線程所獨占

(2) unclock:將lock加的鎖定解除,此時其它的線程可以有機會訪問此變量

(3) read:將主內存中的變量值讀到工作內存當中

(4) load:將read讀取的值保存到工作內存中的變量副本中。

(5) use:將值傳遞給線程的代碼執行引擎

(6) assign:將執行引擎處理返回的值重新賦值給變量副本

(7) store:將變量副本的值存儲到主內存中。

(8) write:將store存儲的值寫入到主內存的共享變量當中。

我們可以看到,要保證數據的同步,lock和unlock定義了一個線程訪問一次共享內存的界限,有lock操作也必須有unlock操作,另外一 些操作也必須要成對出現才可以,像是read和load、store和write需要成對出現,如果單一指令出現,那么就會造成數據不一致的問題。 Java內存模型也針對這些操作指定了必須滿足的規則:

(1) read和load、store和write必須要成對出現,不允許單一的操作,否則會造成從主內存讀取的值,工作內存不接受或者工作內存發起的寫入操作而主內存無法接受的現象。

(2) 在線程中使用了assign操作改變了變量副本,那么就必須把這個副本通過store-write同步回主內存中。如果線程中沒有發生assign操作,那么也不允許使用store-write同步到主內存。

(3) 在對一個變量實行use和store操作之前,必須實行過load和assign操作。

(4) 變量在同一時刻只允許一個線程對其進行lock,有多少次lock操作,就必須有多少次unlock操作。在lock操作之后會清空此變量在工作內存中原 先的副本,需要再次從主內存read-load新的值。在執行unlock操作前,需要把改變的副本同步回主存。

內存可見性

通過上面Java內存模型的概述,我們會注意到這么一個問題,每個線程在獲取鎖之后會在自己的工作內存來操作共享變量,在工作內存中的副本回寫到主 內存,并且其它線程從主內存將變量同步回自己的工作內存之前,共享變量的改變對其它線程是不可見的。那么很多時候我們需要一個線程對共享變量的改動,其它 線程也需要立即得知這個改動該怎么辦呢?比如以下的情景,有一個全局的狀態變量open:

boolean open= true; 

這個變量用來描述對一個資源的打開關閉狀態,true表示打開,false表示關閉,假設有一個線程A,在執行一些操作后將open修改為false:

//線程A

resource.close();  open = false;  

線程B隨時關注open的狀態,當open為true的時候通過訪問資源來進行一些操作:

//線程B

while(open) {    doSomethingWithResource(resource);  }  

當A把資源關閉的時候,open變量對線程B不可見,如果此時open變量的改動尚未同步到線程B的工作內存中,那么線程B就會用一個已經關閉了的資源去做一些操作,因此產生錯誤。

所以對于上面的情景,要求一個線程對open的改變,其他的線程能夠立即可見,Java為此提供了volatile關鍵字,在聲明open變量的時 候加入volatile關鍵字就可以保證open的內存可見性,即open的改變對所有的線程都是立即可見的。volatile保證可見性的原理是在每次 訪問變量時都會進行一次刷新,因此每次訪問都是主內存中最新的版本。

指令重排序

很多介紹JVM并發的書或文章都會談到JVM為了優化性能,采用了指令重排序,但是對于什么是指令重排序,為什么重排序會優化性能卻很少有提及,其實道理很簡單,假設有這么兩個共享變量a和b:

PRivate int a;  private int b;  

在線程A中有兩條語句對這兩個共享變量進行賦值操作:

a = 1;  b = 2;  

假設當線程A對a進行復制操作的時候發現這個變量在主內存已經被其它的線程加了訪問鎖,那么此時線程A怎么辦?等待釋放鎖?不,等待太浪費時間了,它會去嘗試進行b的賦值操作,b這時候沒被人占用,因此就會先為b賦值,再去為a賦值,那么執行的順序就變成了:

b = 2;  a = 1;  

對于在同一個線程內,這樣的改變是不會對邏輯產生影響的,但是在多線程的情況下指令重排序會帶來問題,看下面這個情景:

在線程A中:

context = loadContext();  inited = true;  

在線程B中:

while(!inited ){   sleep  }   doSomethingwithconfig(context);  

假設A中發生了重排序:

inited = true;  context = loadContext();  

那么B中很可能就會拿到一個尚未初始化或尚未初始化完成的context,從而引發程序錯誤。

想到有一條古老的原則很適合用在這個地方,那就是先要保證程序的正確然后再去優化性能。此處由于重排序產生的錯誤顯然要比重排序帶來的性能優化要重 要的多。要解決重排序問題還是通過volatile關鍵字,volatile關鍵字能確保變量在線程中的操作不會被重排序而是按照代碼中規定的順序進行訪 問。

最后的總結

這篇文章簡單的介紹了Java內存模型、內存可見性和指令重排序。不過最后看來其實主要是在解釋volatile這個關鍵字,個人感覺 volatile關鍵字是Java當中最令人困惑和最難理解的關鍵字。相對于synchronized塊的代碼鎖,volatile應該是提供了一個輕量 級的針對共享變量的鎖,當我們在多個線程間使用共享變量進行通信的時候需要考慮將共享變量用volatile來修飾,對于需要使用volatile的各種 情景,看到IBM Developer Works上有一篇文章總結的很不錯,推薦一下: http://www.ibm.com/developerworks/cn/java/j-jtp06197.html

補充說明:64位long和double

在JVM規范中Java內存模型要求lock、unlock、read、load、assign、use、store、write這8個操作必須是 原子的,但是對于64位的long和double來說,如果沒有被volatile修飾符修飾,那么可以不是原子的,注意是可以,即虛擬機在實現的時候可 以選擇是否是原子操作。目前幾乎所有的商用虛擬機都將此實現為原子操作,因此不必每次用到它們都去加volatile修飾。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产在线精品成人一区二区三区| 2019亚洲男人天堂| 精品日韩中文字幕| 欧美成人全部免费| 亚洲性无码av在线| 麻豆乱码国产一区二区三区| 日韩欧美国产中文字幕| 日韩精品中文字幕在线观看| 国产精品网站大全| 日韩欧美在线免费观看| 国产拍精品一二三| 日韩欧美在线国产| 国产69精品久久久久久| 国产日韩中文在线| 欧美日韩免费区域视频在线观看| 欧美激情国产精品| 日本精品视频在线播放| 久久精品一偷一偷国产| 精品国偷自产在线| 久久精品99国产精品酒店日本| 欧美激情极品视频| 国内外成人免费激情在线视频| 亚洲欧洲在线观看| 亚洲人精选亚洲人成在线| 国产91精品不卡视频| 亚洲淫片在线视频| 国产日产亚洲精品| 国产脚交av在线一区二区| 色999日韩欧美国产| 午夜精品美女自拍福到在线| 国产午夜精品一区二区三区| 人九九综合九九宗合| 成人在线视频福利| 国产成人精品久久久| 欧美日韩一区二区免费在线观看| 日韩国产欧美精品一区二区三区| 日韩av网站电影| 国产精品网站视频| 亚洲老板91色精品久久| 欧美综合在线观看| 成人免费网视频| 亚洲综合色激情五月| 久久精品一本久久99精品| 久久久免费精品视频| 97国产精品免费视频| 亚洲自拍偷拍色片视频| 亚洲欧美一区二区精品久久久| 91精品国产高清| 欧美激情一区二区三区高清视频| 日韩国产在线播放| 精品成人69xx.xyz| 久久夜色精品国产欧美乱| 中文字幕国产精品久久| 亚洲欧美一区二区精品久久久| 色诱女教师一区二区三区| 成人乱色短篇合集| 色哟哟亚洲精品一区二区| 亚洲男人第一网站| 青青久久av北条麻妃黑人| 久久免费成人精品视频| 91免费精品视频| 影音先锋欧美精品| 久久久天堂国产精品女人| 国产一区二区三区中文| 亚洲人成网在线播放| 成人a视频在线观看| 欧美精品久久久久久久久| 国产精品国产三级国产aⅴ9色| 日韩三级成人av网| 日韩美女在线播放| 中文综合在线观看| 国产精品成人在线| 久久免费视频网站| 国产一区二区成人| 国产成人精品久久久| 亚洲va码欧洲m码| 久久久视频精品| 最近2019中文字幕在线高清| 97视频在线观看视频免费视频| 亚洲国产精品专区久久| 久久久久久久电影一区| 97人人模人人爽人人喊中文字| 中文综合在线观看| 国产欧美一区二区| 欧美成人精品在线播放| 久久国产精品影视| 中国china体内裑精亚洲片| 欧美日韩在线观看视频小说| 亚洲a成v人在线观看| 亚洲成年网站在线观看| 欧美日韩亚洲91| 国产一区私人高清影院| 亚洲国产毛片完整版| 久久视频国产精品免费视频在线| 亚洲美女av电影| 日韩女优在线播放| 最近中文字幕2019免费| 成人黄色午夜影院| 欧美电影院免费观看| 91色中文字幕| 成人激情黄色网| 国产在线观看不卡| 国产91精品网站| 久热国产精品视频| 国产精品国产三级国产aⅴ浪潮| 不卡在线观看电视剧完整版| 国产成人精品a视频一区www| 欧美国产日韩一区二区| 国产精品三级久久久久久电影| 日韩精品在线免费观看视频| 不卡在线观看电视剧完整版| 亚洲情综合五月天| 亚洲免费影视第一页| 欧洲日本亚洲国产区| 亚洲最新av网址| 亚洲国产日韩精品在线| 久久视频中文字幕| 亚洲欧美国产高清va在线播| 日本三级韩国三级久久| 国产成人鲁鲁免费视频a| 在线视频国产日韩| 日韩成人网免费视频| 一区二区三区www| 久久久亚洲影院你懂的| 亚洲国产精品成人av| 成人久久一区二区三区| 国模视频一区二区| 成人激情在线观看| 久久精品免费电影| 国产精品96久久久久久又黄又硬| 国产精品丝袜白浆摸在线| 成人黄色片网站| 国产精品美女无圣光视频| 欧美三级欧美成人高清www| 亚洲成人精品av| 欧美超级乱淫片喷水| 日韩欧美国产免费播放| 国产日韩在线亚洲字幕中文| 国产精品第3页| 日韩精品视频免费在线观看| 91久久精品美女高潮| 色系列之999| 欧美黄色片在线观看| 欧美日韩国产中文字幕| 久久精视频免费在线久久完整在线看| 欧美丰满老妇厨房牲生活| 最新的欧美黄色| 亚洲一区二区三区毛片| 7m第一福利500精品视频| 亚洲在线视频观看| 久久91超碰青草是什么| 欧洲永久精品大片ww免费漫画| 久久琪琪电影院| 亚洲欧洲在线看| 欧美激情啊啊啊| 日本电影亚洲天堂| 亚州国产精品久久久| 亚洲免费av电影| 亚洲一区二区免费| 国产亚洲精品日韩| 欧美一级大片在线观看| 日韩精品久久久久久久玫瑰园| 国产一区二区av| 精品视频在线播放|