锁的概念及应用场景
1、常见“锁”及使用方式一览表
2、各种锁代码案例
Lock
private readonly object _sync = new object();
public void UpdateState()
{
lock (_sync)
{
// 同步操作
}
}
Monitor
Monitor.Enter(_sync);
try
{
// 同步代码
}
finally
{
Monitor.Exit(_sync);
}
Mutex
var mutex = new Mutex(false, "MyAppUniqueName");
if (mutex.WaitOne(TimeSpan.FromSeconds(3), false))
{
try
{
// 访问共享资源
}
finally
{
mutex.ReleaseMutex();
}
}
SemaPhore/SemaPhoreSlim
private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1);
public async Task AccessResourceAsync()
{
await _semaphore.WaitAsync();
try
{
// 异步访问资源
}
finally
{
_semaphore.Release();
}
}
ReaderWriterLockSlim
private readonly ReaderWriterLockSlim _rwLock = new ReaderWriterLockSlim();
public void ReadData()
{
_rwLock.EnterReadLock();
try
{
// 读取数据
}
finally
{
_rwLock.ExitReadLock();
}
}
public void WriteData()
{
_rwLock.EnterWriteLock();
try
{
// 写入数据
}
finally
{
_rwLock.ExitWriteLock();
}
}
SpinLock/SpinWait
SpinLock spinLock = new SpinLock();
bool lockTaken = false;
try
{
spinLock.Enter(ref lockTaken);
// 操作共享资源
}
finally
{
if (lockTaken) spinLock.Exit();
}
Concurrent Collections
ConcurrentDictionary<string, string> cache = new ConcurrentDictionary<string, string>();
cache.TryAdd("key", "value");
ConcurrentQueue<int> queue = new ConcurrentQueue<int>();
queue.Enqueue(1);
Channel<T>
var channel = Channel.CreateUnbounded<int>();
// 生产者
await channel.Writer.WriteAsync(1);
// 消费者
await foreach (var item in channel.Reader.ReadAllAsync())
{
Console.WriteLine(item);
}