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");
            }

    如下输出:

  • 相关阅读:
    Jquery 跨域请求JSON数据问题
    js定时器实现图片轮播
    Redis数据一致性
    Redis缓存击穿、缓存穿透、缓存雪崩
    数据库连接池druid连接mysql数据库‘链路断开’问题
    Mysql启动错误: Can’t create test file xxx lower-test
    DB2-表空间
    DB2-Schema
    DB2-数据库
    DB2-实例
  • 原文地址:https://www.cnblogs.com/gougou1981/p/12360051.html
Copyright © 2011-2022 走看看