Java 同步基石:synchronized 關鍵字深度解析
synchronized 是 Java 並發編程最核心的同步手段,本文從字節碼層面剖析監視器鎖機制,總結 6 大實戰模式與避坑指南。
底層原理
- 字節碼指令:
monitorenter / monitorexit 配對,編譯器自動插入異常路徑保護
- 對象頭 Mark Word:輕量級鎖 → 膨脹為重量級鎖(ObjectMonitor),依賴操作系統 Mutex
- JVM 優化:偏向鎖、輕量級鎖、自旋鎖、鎖消除、鎖粗化(JDK 6+)
三種鎖定目標
| 代碼形式 | 鎖對象 | 作用範圍 |
synchronized(instanceMethod) | this | 當前實例所有同步方法/塊 |
synchronized(staticMethod) | Class對象 | 該類所有靜態同步方法/塊 |
synchronized(obj) { ... } | obj | 同步塊內代碼,粒度最細 |
6 大實戰模式
- 保護複合操作:
if (map.get(key) == null) map.put(key, value) → 整體同步
- 雙重檢查鎖單例:volatile + 雙重判空 + 同步塊
- 條件等待通知:
wait()/notifyAll() 必須在同步塊內調用
- 縮小同步範圍:只同步共享數據訪問,業務邏輯移出
- 避免死鎖:固定加鎖順序、使用
tryLock 超時、避免嵌套鎖
- 替換方案:
ReentrantLock(可中斷、公平、多條件)、Atomic*(CAS 無鎖)、LongAdder(高並發計數)
常見錯誤
- ❌ 鎖住字符串常量/包裝類(常量池導致跨類意外共享鎖)
- ❌ 同步塊中調用耗時 I/O/睡眠
- ❌ 以為
synchronized 保證原子性(僅保證可見性+有序性+互斥,複合操作仍需整體同步)
- ❌ 靜態/實例方法混用導致鎖對象不同而失效
最佳實踐清單
- 優先用
java.util.concurrent 高級組件(ConcurrentHashMap、CopyOnWriteArrayList、ThreadPoolExecutor)
- 必須用 synchronized 時:私有 final Object lock = new Object() 作為專用鎖
- 保持同步塊極小、無副作用、無阻塞調用
- 配合
@ThreadSafe / @GuardedBy 註解文檔化同步策略
- 上一篇文章: Android 仿微信小視頻錄製控件:MediaRecorder + Camera 完整實現
- 下一篇文章: Java 完整實現 2048 小遊戲:Swing 版附全量源碼
Copyright ©
程式碼之家 All Rights Reserved