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

Java synchronized 關鍵字深度解析:鎖機制、作用域與最佳實務

     編輯:Java 相關知識

核心原理

synchronized 以物件鎖實現互斥:每個 Java 物件天生擁有一把鎖。

三種使用形式

1. 同步實例方法

public synchronized void method() { ... }

鎖為 this (當前實例)。同一實例的所有同步方法互斥。

2. 同步靜態方法

public static synchronized void staticMethod() { ... }

鎖為 ClassName.class (Class 物件)。全類別共享一把鎖。

3. 同步區塊

synchronized (lockObject) {
    // 臨界區
}

鎖為指定物件,粒度更細,效能更好。

鎖作用域對照表

形式鎖物件互斥範圍
synchronized instance methodthis同一實例所有同步方法
synchronized static methodClassName.class全類別所有靜態同步方法
synchronized(this)this區塊內程式碼
synchronized(lockObj)lockObj共用同一 lockObj 的區塊
synchronized(ClassName.class)ClassName.class區塊內程式碼

常見錯誤與避坑

錯誤:鎖住不同物件

// 錯誤:兩個實例鎖不同,無互斥效果
MyClass obj1 = new MyClass();
MyClass obj2 = new MyClass();
new Thread(() -> obj1.syncMethod()).start();
new Thread(() -> obj2.syncMethod()).start(); // 可同時執行!

錯誤:使用字串常量當鎖

// 危險:字串常量池可能被其他類別共用
synchronized ("LOCK") { ... }

最佳實務:私有 final 鎖物件

private final Object lock = new Object();
// 或零長度陣列 (較省記憶體)
private final byte[] lock = new byte[0];

進階技巧

  • 雙重檢查鎖定:單例模式延遲初始化 (需 volatile)
  • 鎖降級:ReentrantReadWriteLock 支援寫鎖降級為讀鎖
  • 條件變數:lock.newCondition() 替代 wait/notify
  • 避免在同步區塊呼叫外部方法:防止死結與效能問題

Java 5+ 替代方案

// 明確鎖
ReentrantLock lock = new ReentrantLock();
lock.lock();
try { ... } finally { lock.unlock(); }

// 原子變數 (無鎖)
AtomicInteger count = new AtomicInteger();
count.incrementAndGet();

// 執行緒區域變數
ThreadLocal tl = ThreadLocal.withInitial(() -> createConn());
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved