synchronized 作用於實例方法 → 鎖 this (當前實例)。synchronized 作用於靜態方法 → 鎖 ClassName.class (類對象)。synchronized(obj) 作用於同步塊 → 鎖 obj (任意對象引用)。| 用法 | 語法 | 鎖對象 | 適用場景 |
|---|---|---|---|
| 同步方法 | public synchronized void method() | 實例方法鎖 this;靜態方法鎖 Class.class | 整個方法需原子性,程式碼簡潔 |
| 同步塊 | synchronized(lockObj) { ... } | 括號內運算式結果對象 | 縮小鎖範圍、提升並發、指定特定鎖對象 |
假設類 Demo 有實例 d1, d2:
d1.syncBlock(),執行緒 B 進入 d1.syncMethod() → B 阻塞,因兩者鎖同一把 d1。d1.syncBlock(),執行緒 B 進入 d1.nonSyncMethod() → 並行執行,非同步方法不獲取鎖。d1.syncMethod(),執行緒 B 進入 d2.syncMethod() → 並行執行,鎖分別是 d1、d2。Demo.staticSync() (鎖 Demo.class),執行緒 B 進入 d1.instanceSync() (鎖 d1) → 並行執行,鎖不同。synchronized(sharedLock) { ... } 可讓不同實例共享同一把鎖,實現跨實例互斥。public class SyncDemo {
private final Object lock = new Object(); // 專用鎖對象 (推薦 private final)
private int count = 0;
// 1. 實例同步方法
public synchronized void incSyncMethod() { count++; }
// 2. 靜態同步方法
public static synchronized void staticSync() { /* ... */ }
// 3. 同步塊 (鎖 this)
public void incSyncBlockThis() { synchronized(this) { count++; } }
// 4. 同步塊 (鎖專用對象) - 推薦做法
public void incSyncBlockPrivate() { synchronized(lock) { count++; } }
// 5. 非同步方法
public void nonSync() { count++; } // 線程不安全!
}
同一執行緒可重複獲取同一把鎖 (計數器 +1),避免自己死鎖自己。
例:同步方法呼叫另一同步方法 (同鎖) 正常執行。
synchronized),合併為單一大鎖。僅能在 synchronized 同步塊/方法內呼叫,釋放鎖並進入等待隊列。
現代替代:java.util.concurrent.locks.Condition (配合 ReentrantLock) 功能更強、語義更清晰。
hashCode 或業務 ID 排序)。ReentrantLock.tryLock(timeout))。java.util.concurrent 高層工具:ReentrantLock, ConcurrentHashMap, AtomicInteger, CountDownLatch, CompletableFuture 等,比手寫 synchronized 更安全、效能更優。private final Object lock = new Object(); (不可變、不可被外部竊取)。String、Integer 等常量池/快取對象 (可能被其他代碼意外共享)。this 於公開 API (外部可竊取鎖導致活鎖/死鎖)。synchronized(ClassName.class) 或 static synchronized;實例資料用實例鎖。ReentrantReadWriteLock 或 StampedLock (JDK 8+)。synchronized 修飾方法等同於 synchronized(this) { 方法體 }?ACC_SYNCHRONIZED 標誌,JVM 直接識別;同步塊用 monitorenter/monitorexit 指令。效能無實質差異。Class.class,實例變數屬於各實例。需在靜態方法內 synchronized(instance) 才能保護該實例變數。synchronized(new Object()) 有意義嗎?volatile?volatile 禁止重排 + 保證可見性。┌─────────────────────────────────────────────────────────────┐
│ synchronized 鎖對象對照表 │
├──────────────────┬────────────────────┬──────────────────────┤
│ 修飾位置 │ 鎖對象 │ 保護範圍 │
├──────────────────┼────────────────────┼──────────────────────┤
│ 實例方法 │ this │ 該實例所有實例欄位 │
│ 靜態方法 │ ClassName.class │ 所有靜態欄位 │
│ 同步塊(obj) │ obj │ 由 obj 決定 │
│ 同步塊(this) │ this │ 同實例方法 │
│ 同步塊(Class.class)│ ClassName.class │ 同靜態方法 │
└──────────────────┴────────────────────┴──────────────────────┘
掌握「鎖是對象、同鎖互斥、不同鎖並行」核心邏輯,配合現代並發工具包,即能寫出高效、安全的多執行緒程式。