线程同步之-旋转门AutoResetEvent

  主要作用:从一个线程向另一个线程发送通知,进行线程同步。

  有点像旋转门,一次只允许一个人通过(一端等待,一端通过,如此循环)

  AutoResetEvent 常常被用来在两个线程之间进行信号发送,两个线程共享相同的AutoResetEvent对象,线程可以通过调用AutoResetEvent对象的WaitOne()方法进入等待状态,然后另外一个线程通过调用AutoResetEvent对象的Set()方法取消等待的状态。

  使用场景:几个线程之间相互交替,或者以某种顺序完成任务时。

参考资源:https://www.cnblogs.com/czytcn/p/8085071.html

     static void Main(string[] args)
        {
            var t = new Thread(() => Process(10));
            t.Start();

            Console.WriteLine("进程开始,主线程.等待另一个线程完成工作(主线程)......");
            
            _workerEvent.WaitOne();//阻止当前线程(主线程到这里阻塞),等子线程(其他任务持有_workerEvent对象的线程)的通知【任务线程调用这个对象的WaitOne都会被阻塞】

            //收到子线程通知,继续执行
            Console.WriteLine("收到子线程完成任务通知了111(主线程)!");
            Thread.Sleep(5000);
            Console.WriteLine("我主线程干活111(主线程)...");
            Thread.Sleep(TimeSpan.FromSeconds(5));
            Console.WriteLine("我主线程干完活了...通知子线程666(主线程)");
            Thread.Sleep(3000);
            _mainEvent.Set();
            
            //Console.WriteLine("Now running the second operation on a second thread");
            
            _workerEvent.WaitOne();//等待子线程

            Console.WriteLine("主线程收到通知888,并最终完成(主线程)!");
            Console.Read();
        }

        private static AutoResetEvent _workerEvent = new AutoResetEvent(false);//交警1
        private static AutoResetEvent _mainEvent = new AutoResetEvent(false);//交警2

        static void Process(int seconds)
        {
            Thread.Sleep(3000);
            //主线程等待时执行的操作
            Console.WriteLine("子线程开始工作(子线程)...");
            Thread.Sleep(TimeSpan.FromSeconds(seconds));
            Console.WriteLine("子线程工作中(子线程)...");
            Thread.Sleep(10000);
            Console.WriteLine("子线程工作完成!并通知主线程开始干活111(子线程)...");

            _workerEvent.Set();//通知主线程可以干活
            
            //Console.WriteLine("子线程开始等待主线程...");
            
            _mainEvent.WaitOne();//等待主线程

            Console.WriteLine("收到主线程通知666,我开干了(子线程)...");
            Thread.Sleep(TimeSpan.FromSeconds(seconds));
            Console.WriteLine("子线程工作完成!通知主线程888(子线程)");
            Thread.Sleep(5000);
            _workerEvent.Set();//通知主线程开始干活
        }

 

上一篇:CF629C Famil Door and Brackets


下一篇:18_接口例题