C#多線程訪問資源的實(shí)現(xiàn)示例
在 C# 中,多線程訪問共享資源需要通過同步機(jī)制來保證線程安全。以下是常見的解決方案及其適用場(chǎng)景:
1.1 鎖機(jī)制
lock關(guān)鍵字- 基于
Monitor類,確保代碼塊同一時(shí)間僅一個(gè)線程進(jìn)入。 - 適用場(chǎng)景:簡(jiǎn)單臨界區(qū)保護(hù)。
private readonly object _lockObj = new object(); lock (_lockObj) { // 訪問共享資源 }- 基于
Monitor類- 提供更靈活的控制(如超時(shí)機(jī)制)。
Monitor.Enter(_lockObj); try { /* 操作資源 */ } finally { Monitor.Exit(_lockObj); }Mutex(互斥鎖)- 跨進(jìn)程同步,適用于多進(jìn)程共享資源。
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 信號(hào)量機(jī)制
Semaphore/SemaphoreSlim- 控制同時(shí)訪問資源的線程數(shù)量。
SemaphoreSlim semaphore = new SemaphoreSlim(3); // 允許3個(gè)線程進(jìn)入 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 事件與信號(hào)
ManualResetEvent/AutoResetEvent- 通過信號(hào)控制線程阻塞與喚醒。
ManualResetEvent mre = new ManualResetEvent(false); mre.WaitOne(); // 等待信號(hào) mre.Set(); // 發(fā)送信號(hào)
Barrier(屏障)- 同步多個(gè)線程到同一階段。
Barrier barrier = new Barrier(3); // 等待3個(gè)線程到達(dá) barrier.SignalAndWait(); // 每個(gè)線程調(diào)用此方法
CountdownEvent- 等待指定數(shù)量的操作完成。
CountdownEvent cde = new CountdownEvent(3); cde.Signal(); // 每個(gè)線程完成后調(diào)用 cde.Wait(); // 等待所有完成
1.4 原子操作
Interlocked類- 提供原子操作(如遞增、比較交換)。
int value = 0; Interlocked.Increment(ref value); // 原子遞增
1.5 線程安全集合
ConcurrentQueue/ConcurrentDictionary等- 內(nèi)置線程安全的集合,避免手動(dòng)同步。
var queue = new ConcurrentQueue<int>(); queue.Enqueue(1); if (queue.TryDequeue(out var item)) { /* 處理元素 */ }
1.6 避免共享狀態(tài)
不可變對(duì)象
- 使用
readonly或不可變集合(如ImmutableList),確保數(shù)據(jù)不可變。
var list = ImmutableList.Create<int>(); list = list.Add(1); // 返回新實(shí)例,原數(shù)據(jù)不變
- 使用
線程本地存儲(chǔ)
- 使用
ThreadLocal<T>或[ThreadStatic]為每個(gè)線程創(chuàng)建獨(dú)立副本。
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 (任務(wù)并行庫(kù))
- 使用
Parallel.For或Task時(shí)確保資源安全。
Parallel.For(0, 10, i => { // 需要內(nèi)部同步機(jī)制 });- 使用
1.8 選擇策略
- 簡(jiǎn)單臨界區(qū):優(yōu)先使用
lock或Monitor。 - 讀寫分離:使用
ReaderWriterLockSlim。 - 高并發(fā)讀:不可變對(duì)象或并發(fā)集合。
- 異步場(chǎng)景:
SemaphoreSlim.WaitAsync()。 - 跨進(jìn)程同步:
Mutex。
通過合理選擇同步機(jī)制,可以平衡性能與線程安全。
到此這篇關(guān)于C#多線程訪問資源的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)C#多線程訪問資源內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C# FileStream實(shí)現(xiàn)大文件復(fù)制
這篇文章主要為大家詳細(xì)介紹了C# FileStream實(shí)現(xiàn)大文件復(fù)制,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-05-05
c#入門之實(shí)現(xiàn)簡(jiǎn)易存款利息計(jì)算器示例
這篇文章主要介紹了c#入門之實(shí)現(xiàn)簡(jiǎn)易存款利息計(jì)算器示例,需要的朋友可以參考下2014-04-04
C#?中?List?與?List?多層嵌套不改變?cè)档膶?shí)現(xiàn)方法(深度復(fù)制)
這篇文章主要介紹了C#?中?List?與?List?多層嵌套不改變?cè)档膶?shí)現(xiàn)方法,使用?BinaryFormatter?將原始?List?序列化為字節(jié)流,然后再反序列化得到新的?List,實(shí)現(xiàn)了深度復(fù)制,需要的朋友可以參考下2024-03-03
C#用表達(dá)式樹構(gòu)建動(dòng)態(tài)查詢的方法
這篇文章主要介紹了C#用表達(dá)式樹構(gòu)建動(dòng)態(tài)查詢的方法,幫助大家更好的理解和學(xué)習(xí)c#,感興趣的朋友可以了解下2020-12-12
C#實(shí)現(xiàn)語(yǔ)音播報(bào)功能
這篇文章主要為大家詳細(xì)介紹了C#實(shí)現(xiàn)語(yǔ)音播報(bào)功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
C#中實(shí)現(xiàn)插入、刪除Excel分頁(yè)符的方法
這篇文章主要給大家介紹了關(guān)于在C#中實(shí)現(xiàn)插入、刪除Excel分頁(yè)符的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-05-05
C#?DataSet結(jié)合FlyTreeView實(shí)現(xiàn)顯示樹狀模型數(shù)據(jù)
NineRays.WebControls.FlyTreeView?是?9rays.net?推出的一款功能強(qiáng)大的樹狀模型數(shù)據(jù)顯示控件,本文主要介紹了如何使用其并結(jié)合?DataSet對(duì)象進(jìn)行數(shù)據(jù)顯示,感興趣的可以了解下2024-04-04

