鎖優化的思路和方法
阿新 • • 發佈:2019-01-08
參見更好的整理
程式碼及虛擬機器配置級別鎖優化
減少鎖持有的時間
- 同步方法細化為同步程式碼塊
減小鎖粒度
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()
清理無用物件。