卓凡

           

          (轉)Java輕量級鎖原理詳解(Lightweight Locking)

          大家知道,Java的多線程安全是基于Lock機制實現的,而Lock的性能往往不如人意。
          原因是,monitorenter與monitorexit這兩個控制多線程同步的bytecode原語,是JVM依賴操作系統互斥(mutex)來實現的。
          互斥是一種會導致線程掛起,并在較短的時間內又需要重新調度回原線程的,較為消耗資源的操作。

          為了優化Java的Lock機制,從Java6開始引入了輕量級鎖的概念。

          輕量級鎖(Lightweight Locking)本意是為了減少多線程進入互斥的幾率,并不是要替代互斥。
          它利用了CPU原語Compare-And-Swap(CAS,匯編指令CMPXCHG),嘗試在進入互斥前,進行補救。

          本文將詳細介紹JVM如何利用CAS,實現輕量級鎖。

           

          原理詳解

          Java Object Model中定義,Object Header是一個2字(1 word = 4 byte)長度的存儲區域。
          第一個字長度的區域用來標記同步,GC以及hash code等,官方稱之為 mark word。第二個字長度的區域是指向到對象的Class。

          在2個word中,mark word是輕量級鎖實現的關鍵。它的結構見下表

          從表中可以看到,state為lightweight locked的那行即為輕量級鎖標記。bitfieds名為指向lock record的指針,這里的lock record,其實是一塊分配在線程堆棧上的空間區域
          用于CAS前,拷貝object上的mark word(為什么要拷貝,請看下文)。
          第三項是重量級鎖標記。后面的狀態單詞很有趣,inflated,譯為膨脹,在這里意思其實是鎖已升級到OS-level。
          在本文的范圍內,我們只關注第二和第三項即可。

          為了能直觀的理解lock,unlock與mark word之間的聯系,我畫了一張流程圖:

          在圖中,提到了拷貝object mark word,由于脫離了原始mark word,官方將它冠以displaced前綴,即displaced mark word(置換標記字)。
          這個displaced mark word是整個輕量級鎖實現的關鍵,在CAS中的compare就需要用它作為條件。

          為什么要拷貝mark word?
          其實很簡單,原因是為了不想在lock與unlock這種底層操作上再加同步。

          在拷貝完object mark word之后,JVM做了一步交換指針的操作,即流程中第一個橙色矩形框內容所述。
          將object mark word里的輕量級鎖指針指向lock record所在的stack指針,作用是讓其他線程知道,該object monitor已被占用。
          lock record里的owner指針指向object mark word的作用是為了在接下里的運行過程中,識別哪個對象被鎖住了。

          下圖直觀地描述了交換指針的操作。

          exchange_pointer_1

          最后一步unlock中,我們發現,JVM同樣使用了CAS來驗證object mark word在持有鎖到釋放鎖之間,有無被其他線程訪問。
          如果其他線程在持有鎖這段時間里,嘗試獲取過鎖,則可能自身被掛起,而mark word的重量級鎖指針也會被相應修改。
          此時,unlock后就需要喚醒被掛起的線程。

          原文鏈接:http://kenwublog.com/theory-of-lightweight-locking-upon-cas

          posted on 2010-01-08 17:59 卓凡 閱讀(272) 評論(0)  編輯  收藏 所屬分類: core java

          導航

          統計

          常用鏈接

          留言簿

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 桦川县| 闽侯县| 社旗县| 长垣县| 洛扎县| 渭南市| 通河县| 海盐县| 修文县| 横山县| 西贡区| SHOW| 大同市| 丰台区| 伊宁县| 崇文区| 黑水县| 苍山县| 司法| 米易县| 珲春市| 绍兴县| 聂拉木县| 通海县| 云霄县| 纳雍县| 商城县| 城步| 衡山县| 那曲县| 沙河市| 东阳市| 渝中区| 玛曲县| 密云县| 沽源县| 离岛区| 景泰县| 盐池县| 仲巴县| 大方县|