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

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

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

2019-11-11 05:27:51
字體:
來源:轉載
供稿:網友

并發本來就是個有意思的問題,尤其是現在又流行這么一句話:“高帥富加機器,窮矮搓搞優化”。從這句話可以看到,無論是高帥富還是窮矮搓都需要深入理解并發編程,高帥富加多了機器,需要協調多臺機器或者多個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
国产视频久久网| 日本精品在线视频| 国产精品白嫩初高中害羞小美女| 国产在线观看精品| 国产综合久久久久| 国产精品视频公开费视频| 亚洲成av人片在线观看香蕉| 久久99精品久久久久久青青91| 91精品免费久久久久久久久| 国产亚洲一级高清| zzijzzij亚洲日本成熟少妇| 日韩精品极品在线观看播放免费视频| 国产一区二区欧美日韩| 久久影院在线观看| 狠狠躁18三区二区一区| 亚洲成人三级在线| 欧美小视频在线观看| 欧美日韩aaaa| 亚洲第一精品电影| 日韩电影中文 亚洲精品乱码| 日韩欧美在线视频日韩欧美在线视频| 亚洲女人被黑人巨大进入| 欧美福利视频在线| 亚洲精品国产美女| 欧美激情乱人伦| 国产精品极品尤物在线观看| 国产欧美日韩亚洲精品| 成人亲热视频网站| 欧美综合在线观看| 成人欧美一区二区三区在线| 欧美国产激情18| 欧美激情在线视频二区| 日韩av在线免费播放| 成人免费xxxxx在线观看| 欧美剧在线观看| 久久精品电影网站| 中国china体内裑精亚洲片| 欧美尺度大的性做爰视频| 久久久久久尹人网香蕉| 国产在线视频一区| 亚洲伊人久久大香线蕉av| 久久精品国产2020观看福利| 久久99热精品这里久久精品| 一区二区三区 在线观看视| 亚洲福利在线看| 成人国产精品一区| 成人免费xxxxx在线观看| 国产91|九色| www.亚洲男人天堂| 91九色在线视频| 国产精品成人av在线| 亚洲天堂免费视频| 97热在线精品视频在线观看| 久久精品成人动漫| 欧美亚洲第一页| 最新69国产成人精品视频免费| 成人网页在线免费观看| 欧美视频在线观看 亚洲欧| 欧美精品www在线观看| 久久久免费精品视频| 亚洲欧美一区二区三区久久| 韩国欧美亚洲国产| 国产黑人绿帽在线第一区| 亚洲美女黄色片| 91精品视频在线| xxxx欧美18另类的高清| 亚洲美女精品成人在线视频| 5566成人精品视频免费| 国产精品欧美日韩| 欧美性猛交xxxx免费看| 国产亚洲一区二区精品| 色综合天天狠天天透天天伊人| 欧美成人激情视频免费观看| 亚洲黄色av网站| 91精品国产91久久久| www国产91| 久久久精品国产亚洲| 992tv成人免费视频| 久久国产天堂福利天堂| 久久久成人精品| 色偷偷av一区二区三区乱| 成人有码在线视频| 国色天香2019中文字幕在线观看| 91久久综合亚洲鲁鲁五月天| 国产成人精品电影| 成人国产精品免费视频| 国产女精品视频网站免费| 国产一区二区三区四区福利| 日本免费一区二区三区视频观看| 激情久久av一区av二区av三区| 国产视频精品一区二区三区| 亚洲高清一区二| 国产精品电影久久久久电影网| 欧美精品18videos性欧| 日韩欧美国产成人| 欧美贵妇videos办公室| 国产成人精品免高潮在线观看| 最新69国产成人精品视频免费| 日韩免费高清在线观看| 欧美精品激情视频| 亚洲精品日韩欧美| 久久久噜久噜久久综合| 国产精品久久在线观看| 日本三级久久久| 自拍亚洲一区欧美另类| 久久久精品视频成人| 欧美日韩精品在线观看| 亚洲福利视频网| 国产+成+人+亚洲欧洲| 欧美性一区二区三区| 欧美一区三区三区高中清蜜桃| 秋霞成人午夜鲁丝一区二区三区| 久久久国产精品一区| 国产精品旅馆在线| 久久久久久九九九| 欧美精品第一页在线播放| 欧美激情性做爰免费视频| 日韩欧美成人免费视频| 国产精品亚洲аv天堂网| 97免费在线视频| 亚洲欧美日韩精品久久奇米色影视| 国外成人在线视频| 欧美视频在线观看 亚洲欧| 亚洲精品网站在线播放gif| 日韩久久免费视频| 2019中文字幕免费视频| 91在线视频精品| 国产成人精品久久| 91av视频在线播放| 欧美日韩中国免费专区在线看| 欧美成人一区二区三区电影| 亚洲视频在线观看视频| 国产精品高潮呻吟久久av黑人| 亚洲激情电影中文字幕| 性夜试看影院91社区| 亚洲自拍av在线| 精品视频在线播放色网色视频| 一区二区欧美激情| 中文字幕亚洲综合久久筱田步美| 日韩成人在线播放| 欧美孕妇与黑人孕交| 亚洲第一精品自拍| 国产精品日韩av| 欧美在线观看一区二区三区| 91av在线免费观看| 精品视频久久久久久| 亚洲欧洲国产一区| 亚洲欧美国产另类| 欧美日韩综合视频网址| 国产精品成人久久久久| 日韩精品久久久久久久玫瑰园| 九九精品视频在线观看| 国产精品久久久久99| 在线日韩欧美视频| 国产精品jvid在线观看蜜臀| 日韩欧美国产免费播放| 国产精品手机播放| 亚洲国产欧美一区二区三区同亚洲| 国内免费久久久久久久久久久| 国产欧美精品xxxx另类| 国产精品视频网| 91精品免费视频| 中文字幕亚洲图片| 久久夜精品va视频免费观看|