.NET 提供豐富的同步原語,各有適用場景與效能特性。本文系統整理 10 大同步機制的實作原理、適用條件與選型建議,協助開發者在正確性與效能間取得平衡。
| 機制 | 原理 | 適用場景 | 注意事項 |
|---|---|---|---|
volatile | 禁止編譯器/CPU 將欄位快取至暫存器,強制從主記憶體讀寫 | 單一變數的跨執行緒可見性(如旗標) | 非原子操作,無法解決複合動作競爭;多核下仍可能因快取一致性延遲失效 |
Interlocked | CPU 專用指令鎖定記憶體匯流排,執行原子增減/交換/比較交換 | 整數計數器、旗標原子翻轉、無鎖資料結構基石 | 僅支援基本型別(int, long, float, double, IntPtr, Object) |
lock / Monitor | 物件頭部 SyncBlockIndex 實作的輕量級互斥鎖,使用者模式自旋後進入核心等待 | 大多數臨界區保護,程式碼簡潔、可重入 | 進程內同步;避免鎖住公開物件或 this/typeof(T) |
| 機制 | 原理 | 適用場景 | 注意事項 |
|---|---|---|---|
Mutex | Win32 Mutex Kernel Object 封裝,跨進程可見,具擁有權語意 | 跨進程同步、單一應用程式實例檢查 | 開銷大(使用者/核心模式切換);僅擁有者可 ReleaseMutex |
Semaphore / SemaphoreSlim | 計數信號,WaitOne 遞減,Release 遞增;Slim 為輕量版 | 資源池限流(連線數、並行度);Slim 適用高頻短暫等待 | 無擁有權,任意執行緒可 Release;計數溢位拋例外 |
AutoResetEvent / ManualResetEvent | Win32 Event 封裝;Auto 釋放單一等待者,Manual 釋放所有 | 執行緒間單次/多次通知協調 | 核心物件,開銷較大;Slim 版本 (.NET 4+) 效能更好 |
lock(this),不建議用於公開 API。WaitForMultipleObjects,WaitAll 需 COM 單一執行緒套房 (STA) 支援,效能較差,慎用。Mutex / 命名 Semaphore / EventWaitHandlevolatile (唯讀可見) / Interlocked (原子寫入)ReaderWriterLockSlimSpinLock (結構體,需 try/finally 釋放)lock (首選)AutoResetEvent / ManualResetEventSlim / SemaphoreSlimTask / SemaphoreSlim.WaitAsync / AsyncLock (社群套件)private readonly object _lock = new object();lock 內呼叫外部虛擬方法/委派。Monitor.TryEnter(timeout) 防止無限期阻塞。Mutex/Semaphore 時捕獲 ApplicationException (擁有權錯誤)。