狂奔 lion

          自強(qiáng)不息

          2010年7月9日

          淺談Java中的同步的方法和原理

          Java的內(nèi)存模型中Thread會(huì)附有自己的堆棧,寄存器,必要時(shí)需要和主存即heap之間同步。
          可以使用Synchornized關(guān)鍵字和Concurrent包中的Lock可以保證線程互斥和可見(jiàn)性。

          互斥性體現(xiàn)在類(lèi)鎖或者對(duì)象鎖上,每個(gè)對(duì)象自身都包含一個(gè)監(jiān)視器,該監(jiān)視器是一個(gè)每次只能被一個(gè)線程所獲取進(jìn)入的臨界區(qū),可以通過(guò)wait和notify來(lái)退出和準(zhǔn)入臨界區(qū)。可以看出這是一個(gè)生產(chǎn)者-消費(fèi)者的模型。而Concurrent包中的Lock為了能夠獲得更好的性能和更好的擴(kuò)展性,以及不依賴(lài)于關(guān)鍵字的可讀代碼,自己實(shí)現(xiàn)了這樣一個(gè)生產(chǎn)消費(fèi)隊(duì)列,也就是AbstractQueuedSynchronizer,被稱(chēng)為AQS的機(jī)制。每個(gè)Lock都內(nèi)置了一個(gè)AbstractQueuedSynchronizer。需要說(shuō)明的是AbstractQueuedSynchronizer內(nèi)部實(shí)現(xiàn)采用了CAS機(jī)制,通過(guò)getState, setState, compareAndSetState訪問(wèn)控制一個(gè)32bit int的形式進(jìn)行互斥。

          那么可見(jiàn)性是如何保證的呢?

          對(duì)于關(guān)鍵字的同步機(jī)制,其實(shí)可見(jiàn)性就是線程和主存之間的同步時(shí)機(jī)問(wèn)題。共有4個(gè)時(shí)間點(diǎn)需要注意:
          1 獲取或釋放類(lèi)鎖/對(duì)象鎖的時(shí)候。Thread保證reload/flush全部變更
          2 volatile就是flush on write或者reload on read
          3 當(dāng)線程首次訪問(wèn)共享變量時(shí),可以得到最新的結(jié)果。
          題外:所以在構(gòu)造方法中公布this時(shí)很危險(xiǎn)的。簡(jiǎn)單的說(shuō),就是構(gòu)造時(shí)不逃脫任何變量,不開(kāi)啟新的線程,只做封裝。關(guān)于安全構(gòu)造,請(qǐng)參考
          http://www.ibm.com/developerworks/cn/java/j-jtp0618/#resources
          4 線程結(jié)束時(shí),所有變更會(huì)寫(xiě)回主存

          關(guān)于Concurrent Lock如何實(shí)現(xiàn)可見(jiàn)性的問(wèn)題,Doug Lea大俠,只在他的論文中提到,按照J(rèn)SR133,Unsafe在getState, setState, compareAndSetState時(shí)保證了線程的變量的可見(jiàn)性,不需要額外的volatile支持,至于具體這些native做了哪些magic就不得而知了,總之,最后的contract就是保證lock區(qū)間的共享變量可見(jiàn)性。開(kāi)發(fā)團(tuán)隊(duì)被逼急了就這樣回答:
          There seems to be a real reluctance to explain the dirty details. I think the question was definitely understood on the concurrent interest thread, and the answer is that synchronized and concurrent locking are intended to be interchangable in terms of memory semantics when implemented correctly. The answer to matfud's question seems to be "trust us.”

          不過(guò)這個(gè)地方的確是開(kāi)發(fā)團(tuán)隊(duì)給我們用戶(hù)迷惑的地方,在同樣應(yīng)用了CAS機(jī)制的Atomic類(lèi)中,都內(nèi)嵌了volatile變量,但是再lock塊中,他告訴我們可以保證可見(jiàn)性。

          感興趣的同學(xué)可以下面的兩個(gè)thread和Doug Lea的thesis:
          http://altair.cs.oswego.edu/pipermail/concurrency-interest/2005-June/001587.html
          http://forums.sun.com/thread.jspa?threadID=631014&start=15&tstart=0
          http://gee.cs.oswego.edu/dl/papers/aqs.pdf

          posted @ 2010-07-09 19:49 楊一 閱讀(1868) | 評(píng)論 (0)編輯 收藏

          <2010年7月>
          27282930123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          導(dǎo)航

          公告

          本人在blogjava上發(fā)表的文章及隨筆除特別聲明外均為原創(chuàng)或翻譯,作品受知識(shí)產(chǎn)權(quán)法保護(hù)并被授權(quán)遵從 知識(shí)分享協(xié)議:署名-非商業(yè)性使用-相同方式共享 歡迎轉(zhuǎn)載,請(qǐng)?jiān)谵D(zhuǎn)載時(shí)注明作者姓名(楊一)及出處(www.aygfsteel.com/yangyi)
          /////////////////////////////////////////
          我的訪問(wèn)者

          常用鏈接

          留言簿(5)

          隨筆分類(lèi)(55)

          隨筆檔案(55)

          相冊(cè)

          Java

          其他技術(shù)

          生活

          最新隨筆

          搜索

          積分與排名

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          自強(qiáng)不息


          用心 - 珍惜時(shí)間,勇于創(chuàng)造
          主站蜘蛛池模板: 湘西| 浦北县| 平乐县| 三门峡市| 汨罗市| 南华县| 北海市| 浦城县| 滨海县| 集贤县| 德江县| 二连浩特市| 黑山县| 资中县| 蒙山县| 鲜城| 库伦旗| 辉县市| 临桂县| 九江县| 阿拉善左旗| 镇江市| 西青区| 四会市| 宝清县| 长子县| 英吉沙县| 江安县| 嘉祥县| 巴塘县| 江都市| 滨海县| 镇平县| 耒阳市| 四川省| 祥云县| 凌海市| 高州市| 临沂市| 仙游县| 泌阳县|