线程同步 #
一、线程同步概述 #
1.1 为什么需要同步 #
- 防止竞态条件
- 保证数据一致性
- 协调线程执行
1.2 同步机制 #
| 机制 | 说明 |
|---|---|
| lock | 简单互斥锁 |
| Monitor | 高级锁操作 |
| Mutex | 跨进程互斥 |
| Semaphore | 信号量 |
| ReaderWriterLock | 读写锁 |
二、lock关键字 #
2.1 基本用法 #
csharp
private readonly object _lock = new();
private int _counter = 0;
public void Increment()
{
lock (_lock)
{
_counter++;
}
}
public int GetCounter()
{
lock (_lock)
{
return _counter;
}
}
2.2 锁对象选择 #
csharp
private static readonly object _staticLock = new();
private readonly object _instanceLock = new();
public void Process()
{
lock (_instanceLock)
{
}
}
public static void StaticProcess()
{
lock (_staticLock)
{
}
}
2.3 避免死锁 #
csharp
private readonly object _lockA = new();
private readonly object _lockB = new();
public void Method1()
{
lock (_lockA)
{
Thread.Sleep(100);
lock (_lockB)
{
}
}
}
public void Method2()
{
lock (_lockA)
{
lock (_lockB)
{
}
}
}
三、Monitor类 #
3.1 Enter/Exit #
csharp
private readonly object _lock = new();
public void DoWork()
{
Monitor.Enter(_lock);
try
{
}
finally
{
Monitor.Exit(_lock);
}
}
3.2 TryEnter #
csharp
public bool TryDoWork(TimeSpan timeout)
{
if (Monitor.TryEnter(_lock, timeout))
{
try
{
DoWork();
return true;
}
finally
{
Monitor.Exit(_lock);
}
}
return false;
}
3.3 Wait/Pulse #
csharp
private readonly object _lock = new();
private bool _flag = false;
public void Waiter()
{
lock (_lock)
{
while (!_flag)
{
Monitor.Wait(_lock);
}
}
}
public void Signaler()
{
lock (_lock)
{
_flag = true;
Monitor.Pulse(_lock);
Monitor.PulseAll(_lock);
}
}
四、Mutex #
4.1 基本用法 #
csharp
private static readonly Mutex _mutex = new();
public void Process()
{
_mutex.WaitOne();
try
{
}
finally
{
_mutex.ReleaseMutex();
}
}
4.2 命名Mutex(跨进程) #
csharp
public class SingleInstance
{
private static Mutex? _mutex;
public static bool TryAcquire()
{
_mutex = new Mutex(true, "MyApp_SingleInstance", out bool createdNew);
return createdNew;
}
public static void Release()
{
_mutex?.ReleaseMutex();
_mutex?.Dispose();
}
}
五、Semaphore #
5.1 Semaphore #
csharp
private static readonly Semaphore _semaphore = new(3, 3);
public void AccessResource()
{
_semaphore.WaitOne();
try
{
}
finally
{
_semaphore.Release();
}
}
5.2 SemaphoreSlim #
csharp
private static readonly SemaphoreSlim _semaphore = new(3, 3);
public async Task AccessResourceAsync()
{
await _semaphore.WaitAsync();
try
{
}
finally
{
_semaphore.Release();
}
}
5.3 限流示例 #
csharp
public class RateLimiter
{
private readonly SemaphoreSlim _semaphore;
public RateLimiter(int maxConcurrent)
{
_semaphore = new SemaphoreSlim(maxConcurrent, maxConcurrent);
}
public async Task<T> ExecuteAsync<T>(Func<Task<T>> action)
{
await _semaphore.WaitAsync();
try
{
return await action();
}
finally
{
_semaphore.Release();
}
}
}
六、ReaderWriterLock #
6.1 ReaderWriterLockSlim #
csharp
private readonly ReaderWriterLockSlim _rwLock = new();
private readonly Dictionary<string, string> _data = new();
public string? Read(string key)
{
_rwLock.EnterReadLock();
try
{
return _data.TryGetValue(key, out var value) ? value : null;
}
finally
{
_rwLock.ExitReadLock();
}
}
public void Write(string key, string value)
{
_rwLock.EnterWriteLock();
try
{
_data[key] = value;
}
finally
{
_rwLock.ExitWriteLock();
}
}
public void Update(string key, string value)
{
_rwLock.EnterUpgradeableReadLock();
try
{
if (_data.ContainsKey(key))
{
_rwLock.EnterWriteLock();
try
{
_data[key] = value;
}
finally
{
_rwLock.ExitWriteLock();
}
}
else
{
_rwLock.EnterWriteLock();
try
{
_data[key] = value;
}
finally
{
_rwLock.ExitWriteLock();
}
}
}
finally
{
_rwLock.ExitUpgradeableReadLock();
}
}
七、AutoResetEvent #
7.1 基本用法 #
csharp
private readonly AutoResetEvent _event = new(false);
public void Waiter()
{
_event.WaitOne();
Console.WriteLine("收到信号");
}
public void Signaler()
{
_event.Set();
}
7.2 生产者消费者 #
csharp
public class ProducerConsumer<T>
{
private readonly Queue<T> _queue = new();
private readonly object _lock = new();
private readonly AutoResetEvent _itemAvailable = new(false);
public void Produce(T item)
{
lock (_lock)
{
_queue.Enqueue(item);
}
_itemAvailable.Set();
}
public T Consume()
{
while (true)
{
lock (_lock)
{
if (_queue.Count > 0)
{
return _queue.Dequeue();
}
}
_itemAvailable.WaitOne();
}
}
}
八、Barrier #
8.1 基本用法 #
csharp
private readonly Barrier _barrier = new(3);
public void Phase1()
{
Console.WriteLine("阶段1完成");
_barrier.SignalAndWait();
}
public void Phase2()
{
Console.WriteLine("阶段2完成");
_barrier.SignalAndWait();
}
九、CountdownEvent #
9.1 基本用法 #
csharp
public void ProcessMultiple(int count)
{
using var countdown = new CountdownEvent(count);
for (int i = 0; i < count; i++)
{
int taskId = i;
Task.Run(() =>
{
DoWork(taskId);
countdown.Signal();
});
}
countdown.Wait();
Console.WriteLine("所有任务完成");
}
十、总结 #
线程同步要点:
| 机制 | 说明 |
|---|---|
| lock | 简单互斥 |
| Monitor | 高级锁 |
| Mutex | 跨进程 |
| Semaphore | 限制并发 |
| ReaderWriterLock | 读写分离 |
下一步,让我们学习高级特性!
最后更新:2026-03-26