class Test {
synchronized static void sayHello3() { }
synchronized void getX() { }
}
| 方法類型 | 鎖對象 | 範圍 |
|---|---|---|
static synchronized | Test.class (Class 物件) | 全進程、所有實例共享 |
synchronized (實例方法) | this (具體實例) | 單一實例 |
Test.class 與 this 是兩個完全不同的物件,Java 監視器機制依據物件身分互斥,故兩把鎖互不干擾。
public class SyncDemo {
static final Object STATIC_LOCK = Test.class;
static final Object INSTANCE_LOCK = new Test();
public static void main(String[] args) {
new Thread(() -> {
synchronized (STATIC_LOCK) {
System.out.println("靜態方法開始");
sleep(1000);
System.out.println("靜態方法結束");
}
}).start();
new Thread(() -> {
synchronized (INSTANCE_LOCK) {
System.out.println("實例方法開始");
sleep(1000);
System.out.println("實例方法結束");
}
}).start();
}
static void sleep(long ms) { try { Thread.sleep(ms); } catch (InterruptedException ignored) {} }
}
輸出會交錯顯示「靜態方法開始」→「實例方法開始」→...,證明並行執行。
private static final Object LOCK = new Object(); 兩方法皆 synchronized(LOCK)。static synchronized(但失去實例隔離性)。java.util.concurrent.Lock (ReentrantLock) 顯式管理鎖,語意更清晰。synchronized(lock) { /* 只保護共享狀態 */ },不要鎖整個方法。理解「鎖的是物件,不是代碼」是 Java 併發編程的基石。