天天看點

并發程式設計之synchronizedjdk1.6後對synchronized的優化

synchronized

    • 局部鎖
    • 全局鎖
  • jdk1.6後對synchronized的優化
    • 重量級鎖
    • synchronized優化
    • 偏向鎖
    • 輕量級鎖
    • 鎖粗化
    • 鎖消除

我們說到并發程式設計我們很容易想到synchronized關鍵字,sychronized是鎖機制中比較常見的同步鎖,synchronized是基于jvm級别的鎖,由jvm管理鎖的擷取與釋放,使用者無需擔心鎖不釋放問題。synchronized可以修飾方法,傳入對象。

局部鎖

synchronized修飾非靜态方法與傳入對象時鎖的對象是非靜态Object,不同的Object之間的鎖互不影響,鎖範圍是目前對象。這時候synchronized鎖類型為局部鎖。

全局鎖

sychronized修飾靜态方法或傳入的對象是靜态對象或單例對象時是全局鎖,synchronized修飾靜态方法時鎖對象是Class,同一個類的Class在jvm中隻有一個,是以構成全局鎖。不同類之間的全局鎖互不影響。如果傳入synchronized的對象時靜态對象或單例對象時,由于在jvm中隻存在一個,是以構成全局鎖。

jdk1.6後對synchronized的優化

重量級鎖

synchronized是基于鎖對象内部一個螢幕鎖(monitor)實作的,螢幕鎖的本質是依賴作業系統的Mutex Lock實作的,當系統檢查到鎖是該類型鎖後會把等待想要擷取鎖的線程阻塞,阻塞或喚醒一個線程時需要作業系統幫忙,從使用者狀态切換到核心狀态,這種切換開銷非常大,花費的時間可能比使用者執行的代碼所花的時間還長。是以synchronized本身是一個重量級鎖。

在java對象頭中記錄了Mark Work資訊,指向資料對象的指針資訊,數組長度資訊。其中Mark Work記錄了hashCode,gc分代年齡,鎖資訊。其中鎖資訊主要為鎖标志位,是否偏向,線程id,指向棧中鎖記錄的指針。

鎖标志位 是否偏向

01 0 無鎖

01 1 偏向鎖,記錄擁有偏向鎖的線程id

00 輕量級鎖,記錄指向獲得輕量級鎖的線程棧的所記錄指針

10 重量級鎖,阻塞未擷取鎖的線程,記錄指向互斥量(重量級鎖)指針

synchronized優化

偏向鎖

根據經驗,大部分時候代碼的執行是不存在競争的,如果采用重量級鎖就會産生不必要的鎖擷取開銷。是以可以先采用偏向鎖,檢查鎖對象頭的鎖資訊是否為無鎖狀态,如果是則使用cas嘗試将鎖對象頭的偏向鎖線程id修改為目前線程id,如果修改成功,擷取偏向鎖成功,修改鎖偏向标志為1,執行同步代碼塊。如果目前線程修改鎖對象頭的偏向鎖線程id為自身id失敗則說明有其他線程擷取了偏向鎖,由于偏向鎖不會自己釋放,在其他線程競争時并且達到安全點(無代碼在執行時,擷取偏向鎖的線程執行完了代碼)釋放。目前線程嘗試執行撤銷偏向鎖,如果偏向鎖在安全點則釋放偏向鎖,恢複無鎖狀态。目前線程重新執行擷取偏向鎖操作。如果目前線程執行偏向鎖釋放時偏向鎖未達到安全點,則撤銷偏向鎖失敗,如果獲得偏向鎖的線程正在運作,則暫停擷取偏向鎖線程,修改鎖對象頭所标志位為00,更新鎖為輕量級鎖,記錄擷取輕量級鎖的線程棧的記錄指針。偏向鎖經常在jvm啟動幾秒種後才激活,可以使用XX:BiasedLockingStartupDelay=0 關閉延遲。如果确認鎖經常處于競争狀态,可以通過-XX:-UseBiasedLocking = false關閉偏向鎖,。

輕量級鎖

鎖更新為輕量級鎖後,虛拟機會在目前線程棧中建立一塊名為Lock Record的空間,用來存儲鎖對象Mark Work的拷貝。拷貝成功後使用cas嘗試将Mark Work的所記錄指針指向Lock Record,如果執行成功擷取輕量級鎖。如果執行不成功重複循環嘗試擷取輕量級鎖。達到一定次數後仍無法擷取輕量級鎖則将Mark Work鎖标志位更新為10,鎖更新為重量級鎖。擷取鎖的線程進入阻塞。擷取輕量級鎖的線程執行完同步代碼後使用cas嘗試将Lock Record替換回到Mark Work,如果成功釋放輕量級鎖,如果失敗說明所已經更新為重量級鎖,目前線程釋放鎖并喚醒一個等待鎖的線程。

鎖狀态 25 bit 4bit 1bit 2bit

23bit 2bit 是否是偏向鎖 鎖标志位

輕量級鎖 指向棧中鎖記錄的指針 00

重量級鎖 指向互斥量(重量級鎖)的指針 10

GC标記 空 11

偏向鎖 線程ID Epoch 對象分代年齡 1 01

鎖粗化

減少不必要的緊連在一起的lock unlock操作,擴大成更大範圍的鎖。

鎖消除

通過編譯器逃逸分析不存在資料共享競争的鎖進行消除。

繼續閱讀