狂奔 lion

          自強不息

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

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

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

          那么可見性是如何保證的呢?

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

          關(guān)于Concurrent Lock如何實現(xiàn)可見性的問題,Doug Lea大俠,只在他的論文中提到,按照JSR133,Unsafe在getState, setState, compareAndSetState時保證了線程的變量的可見性,不需要額外的volatile支持,至于具體這些native做了哪些magic就不得而知了,總之,最后的contract就是保證lock區(qū)間的共享變量可見性。開發(fā)團隊被逼急了就這樣回答:
          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.”

          不過這個地方的確是開發(fā)團隊給我們用戶迷惑的地方,在同樣應用了CAS機制的Atomic類中,都內(nèi)嵌了volatile變量,但是再lock塊中,他告訴我們可以保證可見性。

          感興趣的同學可以下面的兩個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



           @2008 楊一. 版權(quán)所有. 保留所有權(quán)利

          posted on 2010-07-09 19:49 楊一 閱讀(1868) 評論(0)  編輯  收藏 所屬分類: Java SE

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

          導航

          公告

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

          常用鏈接

          留言簿(5)

          隨筆分類(55)

          隨筆檔案(55)

          相冊

          Java

          其他技術(shù)

          生活

          最新隨筆

          搜索

          積分與排名

          最新評論

          閱讀排行榜

          評論排行榜

          自強不息


          用心 - 珍惜時間,勇于創(chuàng)造
          主站蜘蛛池模板: 衡阳县| 平陆县| 资溪县| 桃园县| 凤庆县| 隆化县| 洪湖市| 林周县| 五寨县| 南通市| 临邑县| 东海县| 石家庄市| 巴彦县| 方正县| 安新县| 黄平县| 象州县| 永州市| 霍山县| 吕梁市| 咸宁市| 宁河县| 台江县| 达拉特旗| 达日县| 海盐县| 甘泉县| 团风县| 洱源县| 定兴县| 瑞金市| 萨嘎县| 荃湾区| 饶河县| 凌云县| 平利县| 格尔木市| 新疆| 丰顺县| 正安县|