synchronized 以物件鎖實現互斥:每個 Java 物件天生擁有一把鎖。
public synchronized void method() { ... }
鎖為 this (當前實例)。同一實例的所有同步方法互斥。
public static synchronized void staticMethod() { ... }
鎖為 ClassName.class (Class 物件)。全類別共享一把鎖。
synchronized (lockObject) {
// 臨界區
}
鎖為指定物件,粒度更細,效能更好。
| 形式 | 鎖物件 | 互斥範圍 |
|---|---|---|
| synchronized instance method | this | 同一實例所有同步方法 |
| synchronized static method | ClassName.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") { ... }
private final Object lock = new Object();
// 或零長度陣列 (較省記憶體)
private final byte[] lock = new byte[0];
lock.newCondition() 替代 wait/notify// 明確鎖
ReentrantLock lock = new ReentrantLock();
lock.lock();
try { ... } finally { lock.unlock(); }
// 原子變數 (無鎖)
AtomicInteger count = new AtomicInteger();
count.incrementAndGet();
// 執行緒區域變數
ThreadLocal tl = ThreadLocal.withInitial(() -> createConn());