多線程共享資源時,若無同步機制,會發生競爭條件:執行結果取決於線程執行順序,導致資料不一致、邏輯錯誤。
| 層級 | 類別/關鍵字 | 特性 | 適用場景 |
|---|---|---|---|
| 語言級 | lock | 語法糖,編譯為 Monitor.Enter/Exit,自動 try/finally | 簡單互斥,最常用 |
| 框架級 | Monitor | 提供 TryEnter、Wait/Pulse 等進階功能 | 條件同步、需超時控制 |
| 核心物件 | Mutex | 跨進程、擁有權、放棄偵測 | 單一實例、跨進程同步 |
| 核心物件 | Semaphore/SemaphoreSlim | 計數訊號量,控制並發數量 | 資源池、限流 |
| 核心物件 | AutoResetEvent/ManualResetEvent | 事件訊號,線程間通知 | 工作完成通知、啟動協調 |
| 原子操作 | Interlocked | 硬體級原子,無鎖 | 計數器、旗標、CAS演算法 |
| 高層抽象 | ReaderWriterLockSlim | 讀寫分離,多讀單寫 | 讀多寫少的共享資料 |
| 高層抽象 | Barrier/CountdownEvent | 線程屏障/倒數事件 | 階段性並行協調 |
| 現代非同步 | Task/async/await | 任務導向,避免阻塞線程 | I/O 密集、UI 回應、組合非同步 |
四條件:互斥、佔有並等待、非搶佔、循環等待。預防:固定鎖順序、TryEnter 超時、避免巢狀鎖。
線程持續重試卻永無進展(如兩人走廊避讓)。解決:引入隨機延遲、優先級協商。
低優先級線程長期無法取得資源。解決:公平鎖、優先級反轉保護。
在鎖內呼叫外部代碼/事件,導致死鎖或重入問題。原則:鎖內最小化、不呼叫虛擬方法/委派/事件。
private readonly object sync = new object();,勿鎖 this、typeof(Type)、字串常值。ConcurrentDictionary、BlockingCollection、SemaphoreSlim 等,減少手動同步錯誤。async/await,釋放線程回執行緒池。volatile、Interlocked、Thread.MemoryBarrier 確保跨線程可見。(原文包含三張圖片,展示同步機制分層架構、競爭條件示意、死鎖/活鎖/餓死對比)