| 形式 | 鎖對象 | 並發粒度 | 適用場景 |
|---|---|---|---|
| 實例方法 | this (當前實例) | 同一實例串行 | 實例級臨界區 |
| 靜態方法 | Class 對象 (如 MyClass.class) | 類級串行 (所有實例共享) | 靜態變量操作、單例初始化 |
| 實例方法同步塊 | synchronized(this) 或自定義對象 | 同步塊內串行 | 縮小鎖範圍、提高並發 |
| 靜態方法同步塊 | synchronized(MyClass.class) | 類級串行 | 靜態資源保護 |
public class Counter {
private long count = 0;
// 實例方法同步
public synchronized void add(long v) { count += v; }
// 同步塊縮小範圍
public void add2(long v) { synchronized(this) { count += v; } }
// 靜態同步
private static long staticCount = 0;
public static synchronized void staticAdd(long v) { staticCount += v; }
public static void staticAdd2(long v) { synchronized(Counter.class) { staticCount += v; } }
}
class VolatileDemo {
volatile long v = 0L; // 單次讀寫具有原子性 (含 64 位 long/double)
public void set(long x) { v = x; } // volatile 寫
public long get() { return v; } // volatile 讀
public void inc() { v++; } // 復合操作:讀-改-寫,非原子!
}
編譯器將 volatile 讀寫插入內存屏障:
等價於對每次單次讀寫加同一把監視器鎖 (但無互斥,無上下文切換開銷)。
| 維度 | synchronized | volatile |
|---|---|---|
| 原子性 | ✅ (臨界區串行) | ❌ (僅單次讀寫原子,復合非原子) |
| 可見性 | ✅ (解鎖前刷新、加鎖後失效) | ✅ (內存屏障) |
| 有序性 | ✅ (鎖內串行) | ✅ (禁止重排) |
| 阻塞 | 可能阻塞、上下文切換 | 不阻塞、無切換 |
| 適用對象 | 任意對象/類 | 只能修飾字段 (含靜態/實例) |
| 性能 | 較重 (JDK 6+ 優化:偏向鎖/輕量級鎖/鎖消除/鎖粗化) | 極輕 (近似普通讀寫 + 屏障) |