C# Mutex类实现线程同步(附带实例)
C# 程序中实现线程同步,可以借助 Mutex 类,该类是同步基元,它只向一个线程授予对共享资源的独占访问权。如果一个线程获取了互斥体,则要获取该互斥体的第二个线程将被挂起,直到第一个线程释放该互斥体。
Mutex 类与 Monitor 类似,它防止多个线程在某一时间同时执行某个代码块,然而与监视器不同的是,Mutex 类可以用来使跨进程的线程同步。
Mutex 类的常用方法及说明如下表所示。
使用 Mutex 类实现线程同步时,首先实例化一个 Mutex 对象,其构造函数的语法如下:
【实例】用 Mutex 类设置同步块模拟售票系统,主要代码如下:
Mutex 类与 Monitor 类似,它防止多个线程在某一时间同时执行某个代码块,然而与监视器不同的是,Mutex 类可以用来使跨进程的线程同步。
Mutex 类的常用方法及说明如下表所示。
方法 | 说明 |
---|---|
Close | 在派生类中被重写时,释放由当前 WaitHandle 持有的所有资源 |
ReleaseMutex | 释放 Mutex 一次 |
WaitAll | 等待指定数组中的所有元素都收到信号 |
WaitAny | 等待指定数组中的任一元素收到信号 |
WaitOne | 当在派生类中重写时,阻塞当前线程,直到当前的 WaitHandle 收到信号 |
使用 Mutex 类实现线程同步时,首先实例化一个 Mutex 对象,其构造函数的语法如下:
public Mutex(bool initiallyOwned)参数 initallyOwned 指定了创建该对象的线程是否希望立即获取其所有权,当在一个资源得到保护的类中创建 Mutex 类对象时,通常将该参数设置为 false。
【实例】用 Mutex 类设置同步块模拟售票系统,主要代码如下:
class Program { int num = 10; //设置当前总票数 void Ticket() { while (true) { Mutex myMutex = new Mutex(this); //创建Mutex对象 //阻塞当前线程 myMutex.WaitOne(); //判断当前票数是否大于0 if (num > 0) { Thread.Sleep(100); //使当前线程休眠100毫秒 //票数减1 Console.WriteLine(Thread.CurrentThread.Name + "----票数" + num--); } myMutex.ReleaseMutex() //释放Mutex对象 } } static void Main(string[] args) { Program p = new Program(); //创建对象,以便调用对象方法 Thread tA = new Thread(new ThreadStart(p.Ticket)); //分别实例化4个线程,并设置名称 tA.Name = "线程一"; Thread tB = new Thread(new ThreadStart(p.Ticket)); tB.Name = "线程二"; Thread tC = new Thread(new ThreadStart(p.Ticket)); tC.Name = "线程三"; Thread tD = new Thread(new ThreadStart(p.Ticket)); tD.Name = "线程四"; tA.Start(); //分别启动线程 tB.Start(); tC.Start(); tD.Start(); Console.ReadLine(); } }执行结果为:
线程一----票数10 线程二----票数9 线程三----票数8 线程四----票数7 线程一----票数6 线程二----票数5 线程三----票数4 线程四----票数3 线程一----票数2 线程二----票数1尽管 Mutex 类可以用于进程内的线程同步,但是使用 Monitor 类通常更可取,因为 Monitor 监视器是专门为 .NET Framework 而设计的,因而它可以更好地利用资源。相比之下,Mutex 类是 Win32 构造的包装。尽管 Mutex 类比监视器更为强大,但是相对于 Monitor 类,它所需要的互操作转换更消耗计算资源。