變量分類與同步需求
| 類型 | 定義位置 | 共享性 | 需同步 |
| 局部變量 | 方法內部 | 線程私有 | 否 |
| 類變量 (成員/靜態) | 類中 | 多線程可見 | 是 (有寫操作時) |
純讀操作一般無需同步。
臟數據經典案例
public static int n = 0;
public void run() {
int m = n;
yield(); // 釋放 CPU,放大問題
m++;
n = m;
}
// 100線程並發 → n 遠小於 100 (如 59)
臟數據產生過程圖解
- Thread1:
m = n (0)
- Thread1:
yield() 釋放 CPU
- Thread2:
m = n (0) (n 仍為 0)
- Thread1/2 先後執行
m++ → n=m,最終 n=1
- 100線程重複 → 大量更新丟失

n++ 也不是原子操作!
Java 源碼:n++;
字節碼 (7條指令):
aload_0
dup
getfield // 讀取 n 值到棧
iconst_1
iadd // +1
putfield // 寫回 n
return
中間可被打斷,同樣產生臟數據。
Java 內存模型 (JMM) 解釋
- 主內存:所有實例/靜態變量 (共享)
- 工作內存:線程私有棧 (局部變量、操作數棧)
- 操作流程:主存讀取 → 工作內存修改 → 寫回主存
- 非原子性:讀取/修改/寫回三步可被打斷
解決方案:同步 = 原子操作
強制同一時間僅一線程操作共享變量,將「讀-改-寫」變為不可分割的原子操作。
- 上一篇文章: Java 多線程同步入門:synchronized 關鍵字修飾方法、單例模式線程安全與性能陷阱
- 下一篇文章: Java 多線程數據傳遞與返回:類成員、回調函數與 join 同步三大模式
Copyright ©
程式碼之家 All Rights Reserved