深入多线程之:解析线程的交会(Thread Rendezvous)详解

 更新时间:2013年05月14日 14:48:07   作者:  
本篇文章是对线程的交会(Thread Rendezvous)进行了详细的分析介绍,需要的朋友参考下

在上篇文章中我们使用了Wait和Pulse 实现了Countdown

接下来我们可以使用刚刚写的Countdown 类来实现两个线程的交会。

复制代码 代码如下:

class Rendezvous
    {
        static object _locker = new object();
        static Countdown _countdown = new Countdown(2);

        public static void MainThread()
        {
            Random r = new Random();
            new Thread(Mate).Start(r.Next(1000));
            Thread.Sleep(r.Next(10000)); //主线程睡眠一段时间

            _countdown.Singnal(); //向_countdown注册信号,告知主线程已经来了。
            _countdown.Wait();    //等待其他线程

            Console.WriteLine("Mate!");
        }

        static void Mate(object delay)
        {
            Thread.Sleep((int)delay);//线程睡眠。

            _countdown.Singnal(); //向_countdown注册信号,告知线程已经来了。
            _countdown.Wait();   //等待其他线程。

            Console.WriteLine("Mate!");

        }
}


就像小时候去春游一样,这里的_countdown就是老师,线程就是学生。

学生A早上睡觉,然后起床来到交会点,然后告诉老师,我来了,接着等待老师的出发命令,因为老师知道有两个学生要去春游,所以现在只来了一个,还有一个没有来,所以老师会让学生A等待,阻塞。

学生B也是睡觉,接着也来到交会点,告诉老师,我也来了,然后等待老师的出发命令。

当学生B告诉老师我来了的时候,此时老师的剩余等待学生计数为0,所以老师告诉这两个学生,你们可以出发了。

.net framework 4.0 提供了Barrier 的构造来实现线程交会的功能。如图所示:

Thread1 调用SignalAndWait告知Barrier,我已经来了,然后阻塞。

Thread3调用SignalAndWait告知Barrier,我已经来了,然后阻塞。

Thread2 调用SignalAndWait告知Barrier,我已经来了,Barrier知道现在三个线程都来了,所以让他们继续并发执行。

Barrier的方法简介:

    AddParticipants:增加参与者,也就是增加春游的人数。
    RemoveParticipant:减少参与者,可能某人肚子痛,不能参加春游了。
    SignalAndWait :参与者已经来了,并等待其他参与者的到来。

下面是使用Barrier的示例:

复制代码 代码如下:

static Barrier _barrier = new Barrier(3);//说明有三个参与者

        public static void Main()
        {
            new Thread(Speak).Start();
            new Thread(Speak).Start();
            new Thread(Speak).Start();
        }

        static void Speak()
        {
            for (int i = 0; i < 5; i++)
            {
                Console.Write(i + " ");
                _barrier.SignalAndWait(); //告知参与者已经来了,等待其他参与者
            }
        }


输出如下:

0 0 0 1 1 1 2 2 2 3 3 3 4 4 4

Barrier 的另一个非常有用的特性是在每一个阶段完成的时候你都可以执行一个post-phase 的action委托。

什么是阶段呢??,阶段就是参与者全部都到了的时候。

如果我们修改Barrier的构造函数如下:

static Barrier _barrier = new Barrier(3, (barrier) => Console.WriteLine());

//说明有三个参与者,并且每次三个参与者完成任务的时候执行Console.WriteLine方法.

那么我们的输出如下所示:

0 0 0

1 1 1

2 2 2

3 3 3

4 4 4

相关文章

  • C#实现员工ID卡的识别功能

    C#实现员工ID卡的识别功能

    这篇文章主要为大家详细介绍了C#如何实现识别员工ID卡的功能,文中的示例代码讲解详细,对我们学习C#有一定的帮助,感兴趣的小伙伴可以跟随小编一起了解一下
    2023-01-01
  • Unity使用EzySlice实现模型多边形顺序切割

    Unity使用EzySlice实现模型多边形顺序切割

    这篇文章主要为大家详细介绍了Unity使用EzySlice实现模型多边形顺序切割,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-07-07
  • 解析abstract与override究竟可不可以同时使用

    解析abstract与override究竟可不可以同时使用

    本篇文章是对abstract与override究竟可不可以同时使用进行了详细分析介绍,需要的朋友参考下
    2013-05-05
  • c#编写的番茄钟倒计时器代码

    c#编写的番茄钟倒计时器代码

    番茄钟是老外做饭用的一个厨具,比如蒸包子,水开后再蒸十分钟,就把番茄钟拧一下拧到10的刻度上,然后番茄钟就嗒嗒嗒的慢慢归位,等到十分钟后完全归位,然后就叮的响一声,提醒老外把火关掉。
    2015-03-03
  • C#中Array与ArrayList用法及转换的方法

    C#中Array与ArrayList用法及转换的方法

    C#中Array与ArrayList用法及转换的方法,需要的朋友可以参考一下
    2013-03-03
  • C# 正则表达式常用的符号和模式解析(最新推荐)

    C# 正则表达式常用的符号和模式解析(最新推荐)

    这篇文章主要介绍了C# 正则表达式常用的符号和模式解析,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-12-12
  • C#实现块状链表的项目实践

    C#实现块状链表的项目实践

    这篇文章主要介绍了C#实现块状链表的项目实践,通过定义块和链表类,利用块内元素引用实现块与块之间的链接关系,从而实现对块状链表的遍历、插入和删除等操作,感兴趣的可以了解一下
    2023-11-11
  • C#职责链模式实例详解

    C#职责链模式实例详解

    这篇文章主要介绍了C#职责链模式,以实例形式完整分析了C#职责链模式的相关技巧与实现方法,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-07-07
  • Unity实现场景加载功能

    Unity实现场景加载功能

    这篇文章主要为大家详细介绍了Unity实现场景加载,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10
  • C#判断指定分区是否是ntfs格式的方法

    C#判断指定分区是否是ntfs格式的方法

    这篇文章主要介绍了C#判断指定分区是否是ntfs格式的方法,涉及C#中DriveFormat属性的使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-04-04

最新评论