目录- 1.1 锁机制
- 1.2 信号量机制
- 1.3 事件与信号
- 1.4 原子操作
- 1.5 线程安全集合
- 1.6 避免共享状态
- 1.7 异步与并行
- 1.8 选择策略
在 C# 中,多线程访问共享资源需要通过同步机制来保证线程安全。以下是常见的解决方案及其适用场景:
1.1 锁机制
lock 关键字
- 基于
Monitor 类,确保代码块同一时间仅一个线程进入。 - 适用场景:简单临界区保护。
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 (自旋锁)
SpinLock spinLock = new SpinLock();
bool lockTaken = false;
spinLock.Enter(ref lockTaken);
try { /* 操作资源 */ }
finally { if (lockTaken) spinLock.Exit(); }
1.2 信号量机制
Semaphore / SemaphoreSlim
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(); // 发送信号
Barrier (屏障)
Barrier barrier = new Barrier(3); // 等待3个线程到达
barrier.SignalAndWait(); // 每个线程调用此方法
CountdownEvent
CountdownEvent cde = new CountdownEvent(3);
cde.Signal(); // 每个线程完成后调用
cde.Wait(); // 等待所有完成
1.4 原子操作
Interlocked 类
int value = 0;
Interlocked.Increment(ref value); // 原子递增
1.5 线程安全集合
ConcurrentQueue / ConcurrentDictionary 等
var queue = new ConcurrentQueue<int>();
queue.Enqueue(1);
if (queue.TryDequeue(out var item)) { /* 处理元素 */ }
1.6 避免共享状态
不可变对象
- 使用
readonly 或不可变集合(如 ImmutableList),确保数据不可变。
var list = ImmutableList.Create<int>();
list = list.Add(1); // 返回新实例,原数据不变
线程本地存储
- 使用
ThreadLocal<T> 或 [ThreadStatic] 为每个线程创建独立副本。
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 =>
{
// 需要内部同步机制
});
1.8 选择策略
- 简单临界区:优先使用
lock 或 Monitor。 - 读写分离:使用
ReaderWriterLockSlim。 - 高并发读:不可变对象或并发集合。
- 异步场景:
SemaphoreSlim.WaitAsync()。 - 跨进程同步:
Mutex。
通过合理选择同步机制,可以平衡性能与线程安全。
到此这篇关于C#多线程访问资源的实现示例的文章就介绍到这了,更多相关C#多线程访问资源内容请搜索琼殿技术社区以前的文章或继续浏览下面的相关文章希望大家以后多多支持琼殿技术社区!
您可能感兴趣的文章:- c# 多线程环境下控制对共享资源访问的解决方法
- C#多线程异步执行和跨线程访问控件Helper
- C# 多线程中经常访问同一资源可能造成哪些问题
- C#多线程与跨线程访问界面控件的方法
- c#中多线程访问winform控件的若干问题小结
|