首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

重新認識 synchronized(下):鎖升級、Mark Word、偏向/輕量級/重量級鎖深度解析

     編輯:Java 綜合教學

重新認識 synchronized(下):鎖升級、Mark Word、偏向/輕量級/重量級鎖深度解析

synchronized 鎖機制圖解

synchronized 既保證原子性又保證內存可見性,是 JVM 基於 Monitor 實現的鎖機制。JDK 1.6 引入偏向鎖、輕量級鎖、重量級鎖優化,鎖只能單向升級(無鎖 → 偏向 → 輕量級 → 重量級),不支持降級。

同步語義的雙重含義

  • 互斥:線程退出前,對象狀態變更對其他線程不可見
  • 可見:線程進入同步塊時,能看到上一個線程對對象狀態的最終修改

線程安全 vs 線程同步

  • 線程安全:屬性,多線程環境下不出現數據競爭
  • 線程同步:方式,串行化訪問共享資源,如春運搶票排隊買票

字節碼指令層面實現

// 同步代碼塊:monitorenter / monitorexit
// 同步方法:ACC_SYNCHRONIZED 標志

public void methodA() {
    // 反編譯關鍵指令:
    // 3: monitorenter        ← 獲取鎖
    // ... 方法體
    // 13: monitorexit       ← 釋放鎖(正常退出)
    // 19: monitorexit       ← 釋放鎖(異常退出)
}

異常表確保異常路徑也能釋放鎖,防止死鎖。

鎖升級機制詳解

鎖類型適用場景實現原理優缺點
偏向鎖無競爭、同一線程反復獲取CAS 設置 Mark Word 線程 ID,後續進出無 CAS極低開銷;競爭時需撤銷(全局安全點)
輕量級鎖低競爭、短暫持有CAS 將 Mark Word 指向棧帧 Lock Record,自旋等待避免阻塞喚醒;自旋消耗 CPU,失敗膨脹為重量級
重量級鎖高競爭、長時間持有OS Mutex,線程掛起/喚醒公平調度;上下文切換開銷大

Mark Word 佈局(64位 JVM)

Java synchronized 鎖升級

不同鎖級別 Mark Word

  • 25 bits:HashCode
  • 4 bits:GC 分代年齡
  • 1 bit:偏向鎖標記
  • 54 bits:偏向線程 ID / 指向 Lock Record / 指向 Monitor 對象

關鍵優化參數

  • -XX:BiasedLockingStartupDelay=0:啟動即啟用偏向鎖(默認 4s 延遲)
  • -XX:-UseBiasedLocking:禁用偏向鎖
  • -XX:PreBlockSpin:自旋次數(JDK 1.7+ 自適應)

總結

synchronized 經過多版本演進已非「重鎖」刻板印象。理解鎖升級、Mark Word、自旋優化,能指導鎖粒度設計、減少競爭、排查性能瓶頸。實戰中:縮小同步塊、避免長時間持有鎖、善用併發容器替代顯式鎖。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved