多线程中的ManualResetEvent

先来看一下简单的多线程控制台程序:

using  System;
using  System.Threading;

namespace  ManualResetEventStudy
{

    
class  ThreadClass
    {
        
static   void  t1()
        {
            
for  ( int  x  =   1 ; x  <=   5 ; x ++ )
            {
                Thread.Sleep(
500 );
                Console.WriteLine(
" t1的x: "   +  x);
            }
        }

        
static   void  t2()
        {
            
for  ( int  x  =   1 ; x  <=   5 ; x ++ )
            {
                Thread.Sleep(
500 );
                Console.WriteLine(
" t2的x: "   +  x);
            }
        }

        
static   void  Main( string [] args)
        {
            Thread thrd1 
=   new  Thread(t1);
            thrd1.Start();

            Thread thrd2 
=   new  Thread(t2);
            thrd2.Start();


            
for  ( int  x  =   1 ; x  <=   5 ; x ++ )
            {
                Thread.Sleep(
500 );
                Console.WriteLine(
" 主线程中的x: "   +  x);
            }

            Console.Read();
        }       
    }
}

 入口方法Main里,创建了二个线程,分别调用方法t1与t2,再加上主线程本身,一并有三个线程,运行后,三个线程都在计数输出,结果类似如下:

t2的x:1
t1的x:1
主线程中的x:1
t2的x:2
t1的x:2
主线程中的x:2
t2的x:3
t1的x:3
主线程中的x:3
t2的x:4
t1的x:4
主线程中的x:4
t2的x:5
t1的x:5
主线程中的x:5

 

三个线程的顺序,在这段代码中我们是无法控制的,天知道谁先开始/谁先结束,反正都是"并行"处理,完全看CPU当时的心情  :)

问题:如果需求有变化,比如要求在主线程执行到某个特定的位置(或时间点)时,才让其它线程开始介入,该怎么做呢?(这种情况实际中很常见,比如某一项计算的入口参数依赖于另一项计算的结果,再比如我们计算月工资前,得先统计出员工当月考勤情况)

System.Threading命名空间下有一个ManualResetEvent类,可以做到这一点:

using  System;
using  System.Threading;

namespace  ManualResetEventStudy
{

    
class  ThreadClass
    {       

        
static  ManualResetEvent mre  =   new  ManualResetEvent( false );

        
static   void  t1()
        {
            
mre.WaitOne( 1000 ); // 等待1秒后,自行启动
             for  ( int  x  =   1 ; x  <=   5 ; x ++ )
            {
                Thread.Sleep(
500 );
                Console.WriteLine(
" t1的x: "   +  x);
            }
        }

        
static   void  t2()
        {
            
mre.WaitOne(); // 一直等待下去,直到有"人"调用mre.set()发出信号为止
             for  ( int  x  =   1 ; x  <=   5 ; x ++ )
            {
                Thread.Sleep(
500 );
                Console.WriteLine(
" t2的x: "   +  x);
            }
        }

        
static   void  Main( string [] args)
        {
            Thread thrd1 
=   new  Thread(t1);
            thrd1.Start();

            Thread thrd2 
=   new  Thread(t2);
            thrd2.Start();


            
for  ( int  x  =   1 ; x  <=   5 ; x ++ )
            {
                Thread.Sleep(
500 );
                Console.WriteLine(
" 主线程中的x: "   +  x);

                 if  (x  ==   3
                {
                    mre.Set(); // 通知所有等待的线程:“同志们,可以动啦”:)
                }
            }

            Console.Read();
        }        

    }
}

 t1方法中,我们用 mre.WaitOne(1000);让调用该方法的线程先等候1秒,t2方法中,我们用mre.WaitOne()无限等候,然后主线程中计数到3的时候,手动调用mre.Set()方法唤醒所有等候中的线程,运行结果类似下面这样:

主线程中的x:1
主线程中的x:2
t1的x:1
主线程中的x:3
t1的x:2
t2的x:1
主线程中的x:4
t1的x:3
主线程中的x:5
t2的x:2
t1的x:4
t2的x:3
t1的x:5
t2的x:4
t2的x:5

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值