C# 中的锁
在C#中,实现线程同步和锁定有多种方式。以下是一些常见的锁机制及其详细介绍:
1. lock
关键字
- 描述:这是最简单且常用的同步方法。
lock
实际上是对Monitor.Enter
和Monitor.Exit
的封装,确保即使发生异常也会正确释放锁。 - 使用场景:适用于需要保护共享资源不被多个线程同时访问的场合。
- 示例代码:
private readonly object lockObject = new object();public void CriticalSection() {lock (lockObject){// 临界区代码} }
- 注意点:只能对引用类型加锁;不要使用公共对象如
this
或typeof(TypeName)
来避免不必要的锁竞争。
2. Monitor
类
- 描述:提供了比
lock
更细粒度的控制,允许尝试获取锁(TryEnter)以及指定等待时间等高级功能。 - 使用场景:当你需要更多关于如何获取锁的控制时使用。
- 示例代码:
Monitor.Enter(lockObject); try {// 临界区代码 } finally {Monitor.Exit(lockObject); }
3. Mutex
类
- 描述:互斥量,可以在进程间提供同步。与
Monitor
相比,Mutex
可以跨应用程序域甚至跨进程工作。 - 使用场景:适合需要跨进程同步的场景。
- 示例代码:
using (var mutex = new Mutex(false, "MyMutex")) {mutex.WaitOne();try{// 临界区代码}finally{mutex.ReleaseMutex();} }
4. ReaderWriterLockSlim
- 描述:允许多个线程同时读取数据,但写入时必须独占访问。对于读多写少的情况特别有效。
- 使用场景:当资源主要被读取而较少修改时。
- 示例代码:
var rwLock = new ReaderWriterLockSlim();rwLock.EnterReadLock(); try {// 读操作 } finally {rwLock.ExitReadLock(); }rwLock.EnterWriteLock(); try {// 写操作 } finally {rwLock.ExitWriteLock(); }
5. Semaphore
和 SemaphoreSlim
- 描述:信号量限制了可以同时访问某一资源或资源池的线程数量。
SemaphoreSlim
是轻量级版本,适用于单进程环境。 - 使用场景:当你想要控制同时访问特定资源的最大线程数时。
- 示例代码 (
SemaphoreSlim
):var semaphore = new SemaphoreSlim(3); // 最大并发数为3semaphore.Wait(); try {// 资源访问代码 } finally {semaphore.Release(); }
每种锁都有其适用的场景,选择正确的锁机制可以帮助你有效地管理线程间的同步问题,并提高程序的性能和稳定性。理解这些锁的工作原理和应用场景是编写高效、可靠的多线程应用程序的关键。