1. 程式人生 > >鎖優化的思路和方法

鎖優化的思路和方法

參見更好的整理

程式碼及虛擬機器配置級別鎖優化

減少鎖持有的時間

這裡寫圖片描述

  • 同步方法細化為同步程式碼塊

減小鎖粒度

ConcurrentHashMap實現

這裡寫圖片描述

好處

  • 將大物件拆分為小物件,增大並行度,降低鎖競爭。
  • 偏向鎖、輕量級鎖成功率高。

鎖分離

這裡寫圖片描述

  • ReadWriteLock
  • 讀寫分離,讀鎖之間不會相互阻塞。
  • 聯想forkjoin執行緒池的工作偷取機制
  • LinkedBlockingQueue實現
    Java併發集合實現原理

鎖粗化

這裡寫圖片描述
這裡寫圖片描述

  • 鎖的獲取釋放,也是需要付出一些效能代價的。
  • 針對與那些需要頻繁獲取鎖,釋放鎖的操作,而且每個操作的持有鎖的時間很短。

鎖消除

這裡寫圖片描述

  • 基於編譯器級別的
  • 對於一些執行緒安全的物件,比如StringBuilder,如果該物件是執行緒封閉的,即非逸出物件,那麼該物件就是執行在單執行緒中的,這樣它的同步機制會帶來效能負擔,通過JVM的配置,讓編譯器自動優化這種程式碼。

這裡寫圖片描述

虛擬機器內的鎖優化

偏向鎖

物件頭

  • 32位
  • 描述物件Hash
  • 鎖資訊
  • 垃圾回收標誌
  • 年齡
  • 偏向鎖執行緒ID
    • 已經分配了該鎖的執行緒
    • 在沒有競爭的條件下,獲得偏向鎖的執行緒ID,在進入同步程式碼塊的時候不需要進行同步操作。
    • 適用於競爭少的場景。
    • 命令-XX:+UseBiasedLocking 預設是啟用的

輕量級鎖

  • 快速判斷執行緒是否持該物件的鎖。
  • 線上程棧中開闢一塊空間作為 鎖記錄BasicObjectLock
  • 通過CAS操作,嘗試將修改共享物件的頭資訊中的Mark指標,指向棧空間開闢的 鎖記錄。
  • 如果失敗了,進行自旋。
  • 如果自旋失敗了,則守護共享物件的鎖膨脹為重量級的鎖。
  • 同樣適用於競爭少的情況下。

自旋鎖

  • int i=100 -> while(i--){//空操作}
  • 避免執行緒掛起。

ThreadLocal原始碼實現

ThreadLocalMap核心物件

  • key是ThreadLocal例項 value是需要封閉在當前執行緒中的變數
  • ThreadLocalMap 執行緒的成員變數
    • 內部Entry[] 陣列
    • Entry是繼承自弱引用的WeakReference<ThreadLocal>
  • cleanSomeSlots()清理無用物件。