线程同步 #

一、线程同步概述 #

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