zoukankan      html  css  js  c++  java
  • 多线程CountdownEvent(倒计时事件)--火箭发射!倒计时10,9,8,7,6,5...

    火箭【主线程】起飞前会等待一个倒计时数【定量的子线程不断完成任务,并减少计数】) 

        当主程序启动时,创建了一个CountdownEvent实例,在其构造函数中指定了当两个操作完成时会发生信号。然后我们启动了两个线程,当他们执行完成后会发出信号。一旦第二个线程完成,主线程会从等待CountdownEvent当状态中返回并继续执行。针对需要等待多个异步操作完成当清醒,使用该方式是非常便利的。

          然而这有一个重大的缺点。如果调用_countdown.Signal()没达到指定的次数,那么_countdoun.Wait()将一直等待。请确保使用CountdownEvent时,所有线程完成后都要调用Signal方法

     



         static
    void Main(string[] args) { Console.WriteLine("开始一个操作");

           //启动了两个线程
    var t1 = new Thread(() => PerformOperation("操作1完成", 4)); var t2 = new Thread(() => PerformOperation("操作2完成", 8)); t1.Start(); t2.Start(); _countdown.Wait();//一旦第二个线程完成,主线程会从等待CountdownEvent当状态中返回并继续执行 Console.WriteLine("2个操作都完成了."); _countdown.Dispose(); Console.ReadKey(); } static CountdownEvent _countdown = new CountdownEvent(2);//指定了当两个操作完成时会发生信号 static void PerformOperation(string message, int seconds) { Thread.Sleep(TimeSpan.FromSeconds(seconds)); Console.WriteLine(message); _countdown.Signal();//向 System.Threading.CountdownEvent 注册信号,同时减少其计数。 }

    如下输出:

      再看下面的Task示例

      System.Threading.CountdownEvent  是一个同步基元,它在收到一定次数的信号之后,将会解除对其等待线程的锁定。 CountdownEvent  专门用于以下情况:您必须使用 ManualResetEvent 或 ManualResetEventSlim,并且必须在用信号通知事件之前手动递减一个变量。 例如,在分叉/联接方案中,您可以只创建一个信号计数为 5 的 CountdownEvent,然后在线程池上启动五个工作项,并且让每个工作项在完成时调用 Signal。 每次调用 Signal 时,信号计数都会递减 1。 在主线程上,对 Wait 的调用将会阻塞,直至信号计数为零。 
    CountdownEvent  具有这些附加功能: 
    •可通过使用取消标记来取消等待操作。 
    •创建实例之后可以递增它的信号计数。 
    •通过调用 Reset 方法,可在 Wait 返回之后重用实例。 
    •实例公开 WaitHandle 以便与其他 .NET Framework 同步 API(例如 WaitAll)进行集成。——MSDN

         static void Main(string[] args)
            {
                CountEventTest();
    
                Console.ReadKey();
            }
            private static void CountEventTest()
            {
                
                CountdownEvent count = new CountdownEvent(5);//创建5个数量
                Task[] task = new Task[4];
                count.Reset(4);//重置为4个数量
                Action act = () =>
                {
                    Console.WriteLine("ok");
                    count.Signal();//通知已经有一个线程完成了,计数减1
                };
                for (int i = 0; i < task.Length; ++i)
                {
                    task[i] = new Task(act);
                    task[i].Start();
                }
                count.Wait();//等待4个线程都完成
                Console.WriteLine("end");
            }

    如下输出:

  • 相关阅读:
    Java Native Method
    SQL语句优化
    Ibatis的环境搭建以及遇到的问题解决
    Java 构建器
    SpringMVC自定义视图 Excel视图和PDF视图
    java 枚举的常见使用方法
    mysql 根据某些字段之和排序
    MFC The Screen Flickers When The Image Zoomed
    How To Debug Qmake Pro File
    Gcc And MakeFile Level1
  • 原文地址:https://www.cnblogs.com/gougou1981/p/12360051.html
Copyright © 2011-2022 走看看