深入浅出多线程系列之十四:线程的交会(Thread Rendezvous)

本文介绍了如何使用Countdown类实现两个线程的交会,并通过Barrier构造函数进一步实现多线程的高效同步。通过示例代码,详细解释了线程如何在指定条件下相互等待和唤醒,最终实现并发执行。同时,文章还对比了使用Countdown与Barrier的区别,以及Barrier的额外特性,如阶段完成时执行特定操作。
摘要由CSDN通过智能技术生成

在上篇文章中我们使用了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

 

 

参考资料:

http://www.albahari.com/threading/

CLR Via C# 3.0

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值