public class MyObject {
public synchronized void methodA() {
// 鎖定 this
}
}
等同於:
public void methodA() {
synchronized(this) { /* ... */ }
}
public class MyObject {
public static synchronized void staticMethod() {
// 鎖定 MyObject.class
}
}
public void methodB() {
synchronized(lockObject) { // 可鎖 this、自定義物件、Class 物件
// 臨界區
}
}
同一把鎖同一時間只能被一個執行緒持有。同一物件的多個 synchronized 方法互斥:
public class Counter {
private int count = 0;
public synchronized void increment() { count++; }
public synchronized void decrement() { count--; }
public synchronized int get() { return count; }
}
執行緒 A 呼叫 increment() 時,執行緒 B 呼叫 decrement() 或 get() 會阻塞等待。
synchronized 語義包含 解鎖前將工作記憶體刷新到主記憶體、加鎖後從主記憶體讀取最新值,保證多執行緒對共享變數修改的可見性(JMM happens-before 規則)。
public class UserAccount {
private String username = "default";
private String password = "default";
public synchronized void update(String username, String password) {
this.username = username;
try { Thread.sleep(5000); } catch (InterruptedException e) {}
this.password = password;
}
public synchronized void print() {
System.out.println("user=" + username + ", pwd=" + password);
}
}
update("newUser", "newPass"),執行到 sleep 釋放 CPUprint() 無 synchronized → 執行緒 B 讀到 username="newUser", password="default"(髒讀)| 鎖狀態 | 適用場景 | 特點 |
|---|---|---|
| 無鎖 | 無競爭 | 無開銷 |
| 偏向鎖 | 單一執行緒重複進入 | CAS 設定 ThreadId,後續進入無同步開銷 |
| 輕量級鎖 | 低競爭、短暫持有 | CAS 操作 Mark Word,自旋等待 |
| 重量級鎖 | 高競爭、長時間持有 | OS 互斥量,執行緒阻塞/喚醒 |
synchronized(new Object()) 每次新物件無效;用 final Object lock = new Object()tryLock(timeout)、避免巢狀鎖ReentrantLock(可中斷、公平鎖、Condition)、Atomic*、LongAdder、ConcurrentHashMapsynchronized 是 Java 並發基石,提供互斥與可見性雙重保證。理解鎖對象(this、Class、自定義)、鎖升級機制、JMM 語義,是寫出正確高效並發程式的前提。