n++ 編譯為 4 條 IL 指令:ldloc, ldc.i4.1, add, stloc。執行緒切換導致指令交錯,造成更新遺失:
執行緒1: ldloc(0) ldc.i4.1 add → 切換 執行緒2: ldloc(0) ldc.i4.1 add stloc → n=1 執行緒1: stloc → n=1 (遺失一次遞增)
使用 lock 將多條指令包裝為單一不可分割單元:
lock (lockObj) { n++; } // 任何參考型別物件均可作為鎖
lock (typeof(StaticClass)) { /* 靜態欄位操作 */ }
class Increment {
private int n = 0, max;
private object lockN = new object();
public Increment(int max) { this.max = max; }
public int Result { get => n; set => n = value; }
private void IncN() { lock (lockN) n++; }
public void Inc() { for (int i=0;i
專用鎖物件 lockN 避免外部干擾,封裝 IncN 確保每次遞增原子性。