【多线程系列---AutoResetEvent和ManualResetEvent】

1、多线程AutoResetEvent和ManualResetEvent
 AutoResetEvent 就像一个十字转门,每次只允许一个取消阻塞。
 
static AutoResetEvent auto =  new AutoResetEvent( false);
 
         static  void Main( string[] args)
 
        {
 
            Thread t =  new Thread(WaitFoSingalToWrite);
 
            t.Start();
 
            Thread.Sleep( 2000);
 
            auto.Set();
 
            Console.WriteLine( " Main End... ");
 
        }
 
 
 
         static  void WaitFoSingalToWrite()
 
        {
 
            Console.WriteLine( " in... ");
 
            auto.WaitOne();
 
            Console.WriteLine( " do sth... ");
 
            auto.WaitOne( 3000);
 
            Console.WriteLine( " do sth 1... ");
 
            Console.WriteLine( " out... ");
 
        }
 
 
 
初始的时候,AutoResetEvent构造函数赋值false,意味着一开始就没有信号。线程t运行后遇到block。与此同时的2秒后,Main函数对auto设置了一个信号( set)。此时t可以运行下去。接下来t等待3s后继续执行直至退出。
 
修改代码至如下
 

  static AutoResetEvent auto =  new AutoResetEvent( true);
 
         static  void Main( string[] args)
 
        {
 
            Thread t =  new Thread(WaitFoSingalToWrite);
 
            t.Start();
 
            Thread.Sleep( 2000);
 
             // auto.Set();
 
            Console.WriteLine( " Main End... ");
 
        }
 
 
 
         static  void WaitFoSingalToWrite()
 
        {
 
            Console.WriteLine( " in... ");
 
            auto.WaitOne();
 
            Console.WriteLine( " do sth... ");
 
            auto.WaitOne( 3000);
 
            Console.WriteLine( " do sth 1... ");
 
            Console.WriteLine( " out... ");
 
        }
 
此时尽管t线程有waitone,但是由于初始就给予了一个信号,隐藏,这个block直接就运行下去了。If Set  is called when no thread  is waiting, the handle stays open  for  as  long  as it takes until some thread calls WaitOne.
 
此处即便对多次调用set方法,但是它还是仅对下一个waitone有效,并不是调几次set方法就对几个waitone有效,多调用的set方法纯属浪费。
 

  static AutoResetEvent auto =  new AutoResetEvent( false);
 
         static  void Main( string[] args)
 
        {
 
            Thread t =  new Thread(WaitFoSingalToWrite);
 
            t.Start();
 
            Thread.Sleep( 2000);
 
            auto.Set();
 
            auto.Set();
 
            Console.WriteLine( " Main End... ");
 
        }
 
 
 
         static  void WaitFoSingalToWrite()
 
        {
 
            Console.WriteLine( " in... ");
 
            auto.WaitOne();
 
            Console.WriteLine( " do sth... ");
 
            auto.WaitOne();
 
            Console.WriteLine( " do sth1... ");
 
           
 
            Console.WriteLine( " out... ");
 
        }
 
     此处,虽然调用了2遍,但do sth1仍然被阻塞。
 
 
 
Reset()方法将AutoResetEvent设为无信号状态,但是此方法在AutoResetEvent并没有意义,因为AutoResetEvent发完信号让线程取消阻塞后又自动设为无信号状态了。调用waitOne( 0)相当于reset了AutoResetEvent(只要AutoResetEvent是有信号状态)
 
 ManualResetEvent则像一个普通的门,只要有信号,所有的阻塞都能取消,直到重新Reset。
 
 
 
  static ManualResetEvent manu =  new ManualResetEvent( false);
 
         static  void Main( string[] args)
 
        {
 
            Thread t1 =  new Thread(WaitFoSingalToDo);
 
            Thread t2 =  new Thread(WaitFoSingalToPlay);
 
            t1.Start();
 
            t2.Start();
 
            manu.Set(); 
 
            Thread.Sleep( 5000);
 
            manu.Reset(); 
 
            Console.WriteLine( " Main End... ");
 
        }
 
 
 
         static  void WaitFoSingalToDo()
 
        {
 
            Console.WriteLine( " WaitFoSingalToDo in ... ");
 
            manu.WaitOne();
 
            Console.WriteLine( " do sth... ");
 
            manu.WaitOne();
 
            Console.WriteLine( " do sth1... ");
 
           Console.WriteLine( " out... ");
 
        }
 
 
 
 
 
         static  void WaitFoSingalToPlay()
 
        {
 
            Console.WriteLine( " WaitFoSingalToPlay in... ");
 
            manu.WaitOne();
 
            Console.WriteLine( " play sth... ");
 
            
 
            Thread.Sleep( 10000);
 
            manu.WaitOne();
 
            Console.WriteLine( " play sth1... ");
 
 
 
            Console.WriteLine( " out... ");
 
        }
 
此处,线程t1由于已经有信号,顺畅的运行完毕。t2则运行到play sth...时,等待10秒钟,而此时,5秒钟后,manu将信号Reset(),信号被取消,,所以10秒钟过后,阻塞不能通过。

你可能感兴趣的:(event)