public synchronized void run() { ... } // 實例方法同步
public static synchronized void method() { ... } // 靜態方法同步
效果:同一實例下,所有 synchronized 實例方法互斥;同一類下,所有 synchronized 靜態方法互斥。
Test test1 = new Test();
Test test2 = new Test();
// test1.method() 和 test2.method() 可同時執行!鎖的是不同實例
// 必須共享同一實例才能實現同步
class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
Thread.yield(); // 放大並發問題
instance = new Singleton();
}
return instance;
}
}
// 5線程並發調用 → 可能創建多個實例 (輸出不同 hashCode)
public static synchronized Singleton getInstance()private static final Singleton instance = new Singleton(); (類加載時創建,天然線程安全)| 規則 | 說明 |
|---|---|
| 不可繼承 | 子類覆寫父類 synchronized 方法默認不同步,需顯式加 synchronized 或調用 super.method() |
| 接口方法不可用 | interface 中方法聲明不能加 synchronized |
| 構造方法不可用 | 但可在構造器內用 synchronized 塊 |
| 位置靈活 | public synchronized / synchronized public / public static synchronized / synchronized public static 合法;public void synchronized 非法 |
public synchronized void method1() { while(true); }
public synchronized void method2() { ... }
public static synchronized void method3() { while(true); }
public static synchronized void method4() { ... }
運行結果:method1 執行時 method2 阻塞;method3 執行時 method4 阻塞。
結論:同一類別中,所有 synchronized 實例方法共享一把鎖,所有 synchronized 靜態方法共享另一把鎖。
類比:修改一行數據卻鎖整張表 —— 大量使用導致性能劇降。
ReentrantLock、ConcurrentHashMap 等精細化工具