線程同步是多線程程式設計的基石。在 Windows 8 Store Apps 開發中,.NET 提供了從簡單到進階的多層次同步工具。本文系統梳理 lock/Monitor、Interlocked、Mutex 以及 ReaderWriterLockSlim 的核心機制、效能特徵與適用場景。
lock (obj) { ... } 是 Monitor.Enter/Exit 的語法糖,經編譯器轉換為 try/finally 確保鎖釋放。它是最常用、最安全的互斥方式。
private static readonly object _lockObj = new object();
private static int _counter;
lock (_lockObj) {
for (int i = 0; i < 100000; i++) _counter++;
}
關鍵原則: 鎖物件應為 private static readonly 參考型別,避免使用 this、typeof(Type)、字串或值型別(會導致裝箱產生不同物件)。
Monitor 提供更精細的控制:TryEnter(含超時)、Wait(釋放鎖並進入等待隊列)、Pulse/PulseAll(喚醒等待者)。經典「生產者-消費者」模式:
Monitor.Enter(_lockObj);
try {
while (!condition) Monitor.Wait(_lockObj); // 釋放鎖等待
// 條件滿足,持有鎖繼續
Monitor.Pulse(_lockObj); // 喚醒一個等待者
} finally {
Monitor.Exit(_lockObj);
}
注意: Wait/Pulse 必須在持有鎖期間呼叫,否則拋出 SynchronizationLockException。
Interlocked 類別提供硬體級原子操作,適用於簡單數值型共享變數,效能遠優於鎖。常用方法:
Increment/Decrement:原子遞增/遞減Add:原子加法Exchange:原子交換CompareExchange:CAS(比較並交換),無鎖演算法核心Read:32 位系統上原子讀取 64 位值Interlocked.Increment(ref _counter); // 原子 +1
int oldVal = Interlocked.CompareExchange(ref _value, newVal, expectedVal);
適用場景: 計數器、旗標切換、單一數值欄位更新。不適用: 邏輯複雜、多欄位關聯更新的臨界區。
Mutex(Mutual Exclusion)核心優勢在於跨進程同步。命名 Mutex 可讓不同進程協調共享資源(如單一實例應用、跨進程檔案存取)。
// 單一實例應用經典模式
using (var mutex = new Mutex(true, "MyAppUniqueName", out bool createdNew)) {
if (!createdNew) {
MessageBox.Show("應用程式已在執行中");
return;
}
Application.Run(new MainForm());
}
效能代價: Mutex 屬核心模式物件,切換開銷比 lock/Monitor 大數十倍,進程內同步請勿使用。
針對「讀多寫少」場景,ReaderWriterLockSlim 允許多線程同時讀取,但寫入時獨佔。關鍵特性:
EnterReadLock/ExitReadLock:共享讀鎖,可並發EnterWriteLock/ExitWriteLock:獨佔寫鎖,排他EnterUpgradeableReadLock:可升級為寫鎖的讀鎖,避免死鎖var rwLock = new ReaderWriterLockSlim();
// 高頻讀取
Task.Run(() => {
rwLock.EnterReadLock();
try { ReadData(); }
finally { rwLock.ExitReadLock(); }
});
// 低頻寫入
Task.Run(() => {
rwLock.EnterWriteLock();
try { WriteData(); }
finally { rwLock.ExitWriteLock(); }
});
效能提示: 當寫入頻率較高或臨界區極小時,lock 反而更快。僅在明確「讀多寫少、讀操作耗時」時使用。
| 同步工具 | 核心定位 | 效能層級 | 適用場景 | 跨進程 |
|---|---|---|---|---|
| lock/Monitor | 通用互斥鎖 | 用戶態、中等 | 大多數臨界區保護 | 否 |
| Interlocked | 原子數值操作 | 硬體級、最高 | 單一整數/長整數欄位 | 否 |
| Mutex | 核心互斥鎖 | 核心態、較低 | 跨進程同步、單一實例 | 是 |
| ReaderWriterLockSlim | 讀寫分離鎖 | 用戶態、視爭用 | 讀多寫少、複雜資料結構 | 否 |
readonly,防止引用變更導致同步失效。async 方法中勿用 lock,改用 SemaphoreSlim.WaitAsync 或 AsyncLock 模式。try/finally 或 using 中。根據具體並發特徵選擇合適的同步工具,是構建高效、穩定 Windows 8 Store Apps 的關鍵能力。