多线程同步技术是用于协调多个线程对共享资源的访问,以防止数据竞争、死锁和不一致性问题。以下是 C# 中常用的多线程同步技术的详细说明、适用场景、优缺点以及代码示例,结合上文提到的读写锁,进一步扩展对同步技术的讨论。
1. 多线程同步技术概述在多线程编程中,多个线程可能同时访问共享资源(如变量、对象、文件等),如果不加控制,可能导致:
- 数据竞争:多个线程同时修改共享资源,导致数据不一致。
- 死锁:线程互相等待对方释放资源,造成程序卡死。
- 性能问题:过度同步可能降低并发性能。
C# 提供了多种同步机制,分为锁机制、信号机制和原子操作,适用于不同场景。
2. 常见多线程同步技术
2.1 lock 关键字
- 描述:基于 Monitor 类实现的互斥锁,同一时间只允许一个线程进入受保护的代码块。
- 适用场景:简单场景,保护共享资源的独占访问。
- 优点:简单易用,适合大多数互斥需求。
- 缺点:不支持多读单写,性能在高并发读场景下较差。
- 代码示例:csharp
class Program { private static readonly object _lock = new object(); private static int sharedCounter = 0; static void Main(string[] args) { Task[] tasks = new Task[5]; for (int i = 0; i < 5; i++) { tasks[i] = Task.Run(() => IncrementCounter()); } Task.WaitAll(tasks); Console.WriteLine($"最终计数: {sharedCounter}"); } static void IncrementCounter() { for (int i = 0; i < 1000; i++) { lock (_lock) { sharedCounter++; } } } }- 输出:最终计数: 5000
- 说明:lock 确保 sharedCounter 的增量操作是线程安全的。
2.2 ReaderWriterLockSlim
- 描述:读写锁,允许多个线程同时读取,但写入时独占。
- 适用场景:读多写少的场景,如缓存数据或 COM 组件返回的数据。
- 优点:提高并发读性能。
- 缺点:实现较复杂,写操作可能导致读线程等待。
- 代码示例:见上文 COM 示例,ReaderWriterLockSlim 保护共享数据。
2.3 Monitor
- 描述:lock 的底层实现,提供更细粒度的控制(如 TryEnter 和脉冲等待)。
- 适用场景:需要超时机制或条件等待的场景。
- 优点:灵活,支持复杂同步逻辑。
- 缺点:代码复杂,易出错。
- 代码示例:csharp
class Program { private static readonly object _monitor = new object(); private static int sharedResource = 0; static void Main(string[] args) { Task[] tasks = new Task[2]; tasks[0] = Task.Run(() => Producer()); tasks[1] = Task.Run(() => Consumer()); Task.WaitAll(tasks); } static void Producer() { Monitor.Enter(_monitor); try { sharedResource = 100; Monitor.Pulse(_monitor); // 通知等待的线程 Console.WriteLine("Producer 设置资源"); } finally { Monitor.Exit(_monitor); } } static void Consumer() { Monitor.Enter(_monitor);


1050

被折叠的 条评论
为什么被折叠?



