首页 > 编程笔记 > C#笔记 阅读:5

C# Mutex类实现线程同步(附带实例)

C# 程序中实现线程同步,可以借助 Mutex 类,该类是同步基元,它只向一个线程授予对共享资源的独占访问权。如果一个线程获取了互斥体,则要获取该互斥体的第二个线程将被挂起,直到第一个线程释放该互斥体。

Mutex 类与 Monitor 类似,它防止多个线程在某一时间同时执行某个代码块,然而与监视器不同的是,Mutex 类可以用来使跨进程的线程同步。

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 类,它所需要的互操作转换更消耗计算资源。

相关文章