首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

Windows 8 Store Apps 線程同步基石:lock、Monitor、Interlocked、Mutex 與 ReaderWriterLockSlim

     編輯:關於.NET

前言

線程同步是多線程程式設計的基石。在 Windows 8 Store Apps 開發中,.NET 提供了從簡單到進階的多層次同步工具。本文系統梳理 lock/Monitor、Interlocked、Mutex 以及 ReaderWriterLockSlim 的核心機制、效能特徵與適用場景。

lock 與 Monitor:互斥鎖的雙重面貌

lock:語法糖與最佳實踐

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:底層控制與 Wait/Pulse 模式

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:無鎖原子運算

Interlocked 類別提供硬體級原子操作,適用於簡單數值型共享變數,效能遠優於鎖。常用方法:

  • Increment/Decrement:原子遞增/遞減
  • Add:原子加法
  • Exchange:原子交換
  • CompareExchange:CAS(比較並交換),無鎖演算法核心
  • Read:32 位系統上原子讀取 64 位值
Interlocked.Increment(ref _counter); // 原子 +1
int oldVal = Interlocked.CompareExchange(ref _value, newVal, expectedVal);

適用場景: 計數器、旗標切換、單一數值欄位更新。不適用: 邏輯複雜、多欄位關聯更新的臨界區。

Mutex:跨進程互斥鎖

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:讀寫分離優化

針對「讀多寫少」場景,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讀寫分離鎖用戶態、視爭用讀多寫少、複雜資料結構否

避坑指南

  1. 鎖物件不可變: 必須 readonly,防止引用變更導致同步失效。
  2. 臨界區最小化: 鎖內僅放置必要的共享狀態操作,I/O、運算移至鎖外。
  3. 避免巢狀鎖: 若必須,嚴格遵循固定獲取順序防止死鎖。
  4. 非同步內避免同步阻塞: async 方法中勿用 lock,改用 SemaphoreSlim.WaitAsync 或 AsyncLock 模式。
  5. 正確釋放: 所有鎖操作包裹在 try/finally 或 using 中。

根據具體並發特徵選擇合適的同步工具,是構建高效、穩定 Windows 8 Store Apps 的關鍵能力。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved