C#线程同步:lock与Interlocked实战解析

2 下载量 73 浏览量 更新于2024-09-01 收藏 72KB PDF 举报
"这篇文档详细阐述了C#中实现线程同步的方法,包括lock语句和Interlocked类的使用,提供了实例代码以帮助读者更好地理解和应用这些技术。" 在多线程编程中,线程同步是确保多个线程正确协调执行的关键。C# 提供了几种方法来实现在进程内部的线程同步,防止数据竞争和不一致的状态。 1. 使用lock语句: lock是C#中实现线程同步的基本机制,它通过锁定一个对象来确保同一时间只有一个线程可以访问被锁定的代码块。在提供的示例中,定义了一个名为`SeqLock`的静态私有对象,当多个线程尝试进入`Print`方法时,只有一个线程能够获取到锁并执行代码,其他线程必须等待。lock语句的一个限制是无法设置等待超时,如果线程一直无法获取锁,它将永久等待。 ```csharp private static readonly object SeqLock = new object(); private void Print() { lock (SeqLock) { Console.WriteLine("test"); } } ``` 2. 使用Interlocked类: Interlocked类提供了一组原子操作,能够在多线程环境中安全地更新变量,避免数据竞争。在示例中,Interlocked被用来管理一个单字符缓冲区和一个表示缓冲区占用状态的计数器。`ThreadWriter`线程负责写入字符,而`ThreadReader`线程负责读取字符。`Interlocked.Read`用于安全地读取`numberOfUsedSpace`的值,`Interlocked.Increment`则用于增加计数器,表明缓冲区已被占用。 ```csharp private static char buffer; private static long numberOfUsedSpace = 0; // ... 线程Writer和Reader的创建和启动 ... // 线程Writer部分 for (int i = 0; i < 24; i++) { while (Interlocked.Read(ref numberOfUsedSpace) == 1) { Thread.Sleep(50); } buffer = str[i]; // 向缓冲区写入数据 Interlocked.Increment(ref numberOfUsedSpace); // 写入后,将占用状态设为1 } // 线程Reader部分 for (int i = 0; i < 24; i++) { while (Interlocked.Read(ref numberOfUsedSpace) == 0) { Thread.Sleep(50); } char ch = buffer; // 从缓冲区读取数据 Console.WriteLine(ch); } ``` C# 还提供了其他线程同步机制,如Monitor、Mutex、Semaphore、EventWaitHandle等。这些工具提供了更高级的功能,如等待超时、信号量控制和跨进程同步。然而,lock和Interlocked是最基础也是最常用的,它们适用于许多简单的同步场景。理解并熟练运用这些机制对于编写高效、安全的多线程C#程序至关重要。