C#多線程訪問資源的實現(xiàn)示例
在 C# 中,多線程訪問共享資源需要通過同步機制來保證線程安全。以下是常見的解決方案及其適用場景:
1.1 鎖機制
lock關鍵字- 基于
Monitor類,確保代碼塊同一時間僅一個線程進入。 - 適用場景:簡單臨界區(qū)保護。
private readonly object _lockObj = new object(); lock (_lockObj) { // 訪問共享資源 }- 基于
Monitor類- 提供更靈活的控制(如超時機制)。
Monitor.Enter(_lockObj); try { /* 操作資源 */ } finally { Monitor.Exit(_lockObj); }Mutex(互斥鎖)- 跨進程同步,適用于多進程共享資源。
using var mutex = new Mutex(false, "GlobalMutexName"); mutex.WaitOne(); try { /* 操作資源 */ } finally { mutex.ReleaseMutex(); }SpinLock(自旋鎖)- 通過循環(huán)等待避免上下文切換,適用于極短臨界區(qū)。
SpinLock spinLock = new SpinLock(); bool lockTaken = false; spinLock.Enter(ref lockTaken); try { /* 操作資源 */ } finally { if (lockTaken) spinLock.Exit(); }
1.2 信號量機制
Semaphore/SemaphoreSlim- 控制同時訪問資源的線程數(shù)量。
SemaphoreSlim semaphore = new SemaphoreSlim(3); // 允許3個線程進入 await semaphore.WaitAsync(); try { /* 操作資源 */ } finally { semaphore.Release(); }ReaderWriterLockSlim- 讀寫分離鎖,允許多讀單寫。
ReaderWriterLockSlim rwLock = new ReaderWriterLockSlim(); rwLock.EnterReadLock(); // 讀模式 try { /* 讀取資源 */ } finally { rwLock.ExitReadLock(); } rwLock.EnterWriteLock(); // 寫模式 try { /* 修改資源 */ } finally { rwLock.ExitWriteLock(); }
1.3 事件與信號
ManualResetEvent/AutoResetEvent- 通過信號控制線程阻塞與喚醒。
ManualResetEvent mre = new ManualResetEvent(false); mre.WaitOne(); // 等待信號 mre.Set(); // 發(fā)送信號
Barrier(屏障)- 同步多個線程到同一階段。
Barrier barrier = new Barrier(3); // 等待3個線程到達 barrier.SignalAndWait(); // 每個線程調(diào)用此方法
CountdownEvent- 等待指定數(shù)量的操作完成。
CountdownEvent cde = new CountdownEvent(3); cde.Signal(); // 每個線程完成后調(diào)用 cde.Wait(); // 等待所有完成
1.4 原子操作
Interlocked類- 提供原子操作(如遞增、比較交換)。
int value = 0; Interlocked.Increment(ref value); // 原子遞增
1.5 線程安全集合
ConcurrentQueue/ConcurrentDictionary等- 內(nèi)置線程安全的集合,避免手動同步。
var queue = new ConcurrentQueue<int>(); queue.Enqueue(1); if (queue.TryDequeue(out var item)) { /* 處理元素 */ }
1.6 避免共享狀態(tài)
不可變對象
- 使用
readonly或不可變集合(如ImmutableList),確保數(shù)據(jù)不可變。
var list = ImmutableList.Create<int>(); list = list.Add(1); // 返回新實例,原數(shù)據(jù)不變
- 使用
線程本地存儲
- 使用
ThreadLocal<T>或[ThreadStatic]為每個線程創(chuàng)建獨立副本。
ThreadLocal<int> threadLocal = new ThreadLocal<int>(() => 0); int localValue = threadLocal.Value;
- 使用
1.7 異步與并行
async/await與異步鎖- 在異步代碼中使用
SemaphoreSlim.WaitAsync()。
private SemaphoreSlim asyncLock = new SemaphoreSlim(1); await asyncLock.WaitAsync(); try { /* 異步操作資源 */ } finally { asyncLock.Release(); }- 在異步代碼中使用
TPL (任務并行庫)
- 使用
Parallel.For或Task時確保資源安全。
Parallel.For(0, 10, i => { // 需要內(nèi)部同步機制 });- 使用
1.8 選擇策略
- 簡單臨界區(qū):優(yōu)先使用
lock或Monitor。 - 讀寫分離:使用
ReaderWriterLockSlim。 - 高并發(fā)讀:不可變對象或并發(fā)集合。
- 異步場景:
SemaphoreSlim.WaitAsync()。 - 跨進程同步:
Mutex。
通過合理選擇同步機制,可以平衡性能與線程安全。
到此這篇關于C#多線程訪問資源的實現(xiàn)示例的文章就介紹到這了,更多相關C#多線程訪問資源內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
OpenCvSharp實現(xiàn)Mat對象簡單的像素操作
這篇文章主要介紹了OpenCvSharp實現(xiàn)Mat對象簡單的像素操作,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-11-11
在C# .NET Core中繪制Chart圖表并導出到PDF的實現(xiàn)方法
正好最近的項目需要在后端繪制Chart圖標并進行導出,查閱相關資料后想著記錄以下,本文將詳細介紹在.NET Core環(huán)境中如何繪制Chart圖表并將其導出到PDF文檔中,并分析這種實現(xiàn)方式的技術價值和應用場景,需要的朋友可以參考下2025-10-10
C#使用System.Environment獲取電腦的相關屬性
這篇文章主要為大家詳細介紹了C#使用System.Environment獲取電腦的相關屬性,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-10-10
C#使用Spire.Doc for .NET將HTML轉換為圖像
在C#開發(fā)中,借助Spire.Doc for .NET庫,開發(fā)者可通過簡潔代碼將HTML內(nèi)容高效轉換為多種圖像格式,下面小編就來和大家介紹一下具體實現(xiàn)方法吧2025-10-10

