一、基本介绍
线程锁通常指的是lock
关键字,它用于确保当一个线程位于代码的临界区时,其他线程不进入该区。lock
通常用于保护共享资源,避免竞争条件。
二、关键点
锁(Lock):lock
关键字是C#中用于实现线程同步的最常用方法。它确保一个线程在执行代码块时,其他线程不能进入这个代码块。
private readonly object _lockObject = new object();
public void SomeMethod()
{
lock (_lockObject)
{
// 受保护的代码
}
}
Monitor:Monitor
类提供了更灵活的锁定机制。它允许尝试进入锁定状态(TryEnter
),设置超时(Wait
),以及在不需要时释放锁(Pulse
和Exit
)。
private readonly object _lockObject = new object();
public void SomeMethod()
{
Monitor.Enter(_lockObject);
try
{
// 受保护的代码
}
finally
{
Monitor.Exit(_lockObject);
}
}
Mutex:Mutex
是一种跨进程的同步机制,它允许不同进程间的线程同步。在C#中,Mutex
类提供了这种功能。
using System.Threading;
Mutex mutex = new Mutex();
public void SomeMethod()
{
mutex.WaitOne();
try
{
// 受保护的代码
}
finally
{
mutex.ReleaseMutex();
}
}
Semaphore:Semaphore
是一个计数信号量,它允许多个线程同时访问资源,但是限制了同时访问的最大线程数。
using System.Threading;
Semaphore semaphore = new Semaphore(3, 3);
public void SomeMethod()
{
semaphore.WaitOne();
try
{
// 受保护的代码
}
finally
{
semaphore.Release();
}
}
ReaderWriterLockSlim:这是一种更轻量级的锁,专为读多写少的场景设计。它允许多个读操作并行执行,但写操作是独占的。
using System.Threading;
ReaderWriterLockSlim rwLock = new ReaderWriterLockSlim();
public void ReadMethod()
{
rwLock.EnterReadLock();
try
{
// 读取操作
}
finally
{
rwLock.ExitReadLock();
}
}
public void WriteMethod()
{
rwLock.EnterWriteLock();
try
{
// 写入操作
}
finally
{
rwLock.ExitWriteLock();
}
}
AsyncLock:在异步编程中,传统的锁机制可能不适用,因为它们不支持异步等待。AsyncLock
是一个异步锁,它允许异步方法在等待锁时释放线程。
using System.Threading.Tasks;
using System.Threading;
public class AsyncLock
{
private readonly object _lockObject = new object();
private readonly Task<Releaser> _releaserTask = Task.FromResult(new Releaser(null));
public async Task EnterAsync()
{
var releaser = await _releaserTask;
lock (_lockObject)
{
releaser = await _releaserTask.ConfigureAwait(false);
}
await releaser.DisposeAsync();
}
private class Releaser : IDisposable
{
private readonly TaskCompletionSource<bool> _tcs = new TaskCompletionSource<bool>();
public Releaser(TaskCompletionSource<bool> tcs)
{
_tcs = tcs;
}
public async Task DisposeAsync()
{
lock (_lockObject)
{
_releaserTask = _tcs.Task;
}
_tcs.TrySetResult(true);
}
}
}
三、注意事项
- 避免死锁:确保在代码中不会有两个或更多的线程相互等待对方释放锁。
- 避免资源争用:尽量减少锁的持有时间,以减少线程等待时间。
- 考虑性能:不同的锁机制有不同的性能特性,选择合适的锁机制可以提高程序性能。