
























前言
在多线程编程中,线程之间的资源共享和并发访问可能导致数据竞争、死锁等严重问题。因此,线程同步机制是保障程序正确性和稳定性的重要手段。
C# 提供了多种同步机制,包括 lock、Interlocked、Monitor、SpinLock、WaitHandle、Mutex、Semaphore、Events、Barrier 和 ReaderWriterLockSlim 等。它们虽然都用于线程同步,但在底层实现、适用场景和性能特点上各有不同。
本文将从底层原理、使用方式、性能对比等方面对这些机制进行系统性分析,帮助开发根据实际需求选择最合适的同步策略。
正文
1、lock 关键字
底层操作
特点
示例代码
private staticreadonlyobject _lock = newobject();
privatestaticint _counter = 0;
public static void IncrementCounter()
{
lock (_lock)
{
_counter++;
}
}
2、Interlocked 类
底层操作
特点
示例代码
private static int _counter = 0;
public static void IncrementCounter()
{
Interlocked.Increment(ref _counter);
}
3、Monitor 类
底层操作
特点
示例代码
private staticreadonlyobject _lock = newobject();
public static void DoWork()
{
Monitor.Enter(_lock);
try
{
// 临界区代码
}
finally
{
Monitor.Exit(_lock);
}
}
4、SpinLock 结构
底层操作
特点
示例代码
private static SpinLock _spinLock = new SpinLock();
public static void DoWork()
{
bool lockTaken = false;
try
{
_spinLock.Enter(ref lockTaken);
// 临界区代码
}
finally
{
if (lockTaken)
_spinLock.Exit();
}
}
5、WaitHandle 类
底层操作
特点
示例代码
private static EventWaitHandle _waitHandle = new AutoResetEvent(false);
public static void DoWork()
{
_waitHandle.WaitOne(); // 等待信号
// 继续执行
}
public static void Signal()
{
_waitHandle.Set(); // 发送信号
}
6、Mutex 类
底层操作
特点
示例代码
private static Mutex _mutex = new Mutex();
public static void DoWork()
{
_mutex.WaitOne();
try
{
// 临界区代码
}
finally
{
_mutex.ReleaseMutex();
}
}
7、Semaphore 类
底层操作
特点
示例代码
private static Semaphore _semaphore = new Semaphore(3, 3); // 最多允许3个线程访问
public static void DoWork()
{
_semaphore.WaitOne();
try
{
// 临界区代码
}
finally
{
_semaphore.Release();
}
}
8、Events 类
底层操作
特点
示例代码
private static ManualResetEventSlim _event = new ManualResetEventSlim(false);
public static void DoWork()
{
_event.Wait(); // 等待信号
// 继续执行
}
public static void Signal()
{
_event.Set(); // 发送信号
}
9、Barrier 类
底层操作
特点
示例代码
private static Barrier _barrier = new Barrier(3); // 等待3个线程
public static void DoWork()
{
// 执行部分工作
_barrier.SignalAndWait(); // 等待其他线程
// 继续执行
}
10、ReaderWriterLockSlim 类
底层操作
特点
示例代码
private static ReaderWriterLockSlim _rwLock = new ReaderWriterLockSlim();
public static void Read()
{
_rwLock.EnterReadLock();
try
{
// 读取操作
}
finally
{
_rwLock.ExitReadLock();
}
}
public static void Write()
{
_rwLock.EnterWriteLock();
try
{
// 写入操作
}
finally
{
_rwLock.ExitWriteLock();
}
}
总结对比表
|
同步机制 |
底层实现 |
性能 |
适用场景 |
跨进程支持 |
递归锁支持 |
|
lock |
Monitor |
中等 |
简单临界区保护 |
❌ |
✅ |
|
Interlocked |
CPU 原子指令 |
高 |
简单数值操作 |
❌ |
❌ |
|
Monitor |
SyncBlock |
中等 |
复杂同步逻辑 |
❌ |
✅ |
|
SpinLock |
自旋等待 |
高 |
短时间临界区 |
❌ |
❌ |
|
WaitHandle |
内核事件 |
低 |
信号通知 |
✅ |
❌ |
|
Mutex |
内核互斥体 |
低 |
跨进程同步 |
✅ |
✅ |
|
Semaphore |
内核信号量 |
低 |
资源限制访问 |
✅ |
❌ |
|
Events |
内核事件 |
低 |
信号通知 |
✅ |
❌ |
|
Barrier |
自旋+事件 |
高 |
多线程同步点 |
❌ |
❌ |
|
ReaderWriterLockSlim |
自旋+事件 |
高 |
读写分离场景 |
❌ |
✅ |
选择建议
总结
每种同步机制都有其独特的优势和局限性。在实际开发中,应根据具体场景选择最合适的机制:
掌握这些机制的底层原理和使用方法,有助于编写出更加高效、稳定、安全的多线程程序。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。