zoukankan      html  css  js  c++  java
  • 多线程编程(5)WaitEvent

    还是线程同步问题.

    餐馆吃菜

    即假设3个线程同步进行,但必须是有序进行的,不然线程就会错乱。比如

    1. 厨师烧菜
    2. 服务员端菜
    3. 顾客吃菜

    上面的事情必须按照1,2,3的顺序来完成,意思即3在等2,2在等1.

    顾客会一直催服务员,服务员会一直催厨师,如下示例

    public class Demo3
    {
        AutoResetEvent event1;
        AutoResetEvent event2;
        public Demo3()
        {
            event1 = new AutoResetEvent(false);
            event2 = new AutoResetEvent(false);
            ThreadPool.QueueUserWorkItem(new WaitCallback(Task1));
            ThreadPool.QueueUserWorkItem(new WaitCallback(Task2));
            ThreadPool.QueueUserWorkItem(new WaitCallback(Task3));
        }
    
        public void Task1(object obj)
        {
            Console.WriteLine(DateTime.Now);
            Console.WriteLine("烧菜");
            Thread.Sleep(3000);
            event1.Set();
        }
    
        public void Task2(object obj)
        {
            event1.WaitOne();
            Console.WriteLine(DateTime.Now);
            Console.WriteLine("端菜");
            Thread.Sleep(2000);
            event2.Set();
        }
    
        public void Task3(object obj)
        {
            event2.WaitOne();
            Console.WriteLine(DateTime.Now);
            Console.WriteLine("吃菜);
        }
    }

    结果

    image

    通过这种方式就保持线程可以有条理的工作

    组合模块(WaitAll)

    就像开发程序一样,先是分模块开发,然后是合并

    public class Demo4
    {
        AutoResetEvent[] events;
        public Demo4()
        {
            events = new AutoResetEvent[]{
            new AutoResetEvent(false),
            new AutoResetEvent(false),
            new AutoResetEvent(false)
            };
    
            ThreadPool.QueueUserWorkItem(new WaitCallback(Task1));
            ThreadPool.QueueUserWorkItem(new WaitCallback(Task2));
            ThreadPool.QueueUserWorkItem(new WaitCallback(Task3));
    
            WaitHandle.WaitAll(events);
            Console.WriteLine("Complete");
        }
    
        public void Task1(object obj)
        {
            Thread.Sleep(1000);
            Console.WriteLine(DateTime.Now);
            Console.WriteLine("Task1");
            events[0].Set();
        }
    
        public void Task2(object obj)
        {
            Thread.Sleep(2000);
            Console.WriteLine(DateTime.Now);
            Console.WriteLine("Task2");
            events[1].Set();
        }
    
        public void Task3(object obj)
        {
            Thread.Sleep(3000);
            Console.WriteLine(DateTime.Now);
            Console.WriteLine("Task3");
            events[2].Set();
        }
    }

    结果

    image

    秒杀商品(AutoReset)

    现在假设有3个人抢1件商品,3个人在等的就是时间的开始,时间一开始就开始秒杀.但只有一人才能成功,即3个人是抢占的

    使用AutoResetEvent(只能激活一个线程)完成,下面只有一个线程进来,至于是哪个,谁也不知道

    public class Demo5
    {
        EventWaitHandle eventHandle;
        public Demo5()
        {
            eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset);
    
            ThreadPool.QueueUserWorkItem(new WaitCallback(Task1));
            ThreadPool.QueueUserWorkItem(new WaitCallback(Task2));
            ThreadPool.QueueUserWorkItem(new WaitCallback(Task3));
    
            eventHandle.Set();
        }
    
        public void Task1(object obj)
        {
            eventHandle.WaitOne();
            Thread.Sleep(1000);
            Console.WriteLine(DateTime.Now);
            Console.WriteLine("Task1");
        }
    
        public void Task2(object obj)
        {
            eventHandle.WaitOne();
            Thread.Sleep(1000);
            Console.WriteLine(DateTime.Now);
            Console.WriteLine("Task2");
        }
    
        public void Task3(object obj)
        {
            eventHandle.WaitOne();
            Thread.Sleep(1000);
            Console.WriteLine(DateTime.Now);
            Console.WriteLine("Task3");
        }
    }

    image

    短跑比赛(ManualReset)

    裁判员哨子一吹,全体运动员开跑,即ManualResetEvent可以激活多个线程,改为ManualResetEvent的结果如下

    image

    以上4个示例,展示了线程同步的问题

  • 相关阅读:
    整数数组中最大子数组的和的问题(续)
    整数数组中最大子数组的和的问题
    PHP开发环境(Apache+mysql+PHPstorm+php)的搭建
    echart 库 初始
    2.15 学习总结 之 天气预报APP volley(HTTP库)之StringRequest
    2.14 学习总结 之 序列化
    2.13 阶段实战 使用layui重构选课系统
    2.12 学习总结 之 表单校验插件validate
    jsp连接数据库的乱码问题 servlet请求参数编码处理get post
    Rocket
  • 原文地址:https://www.cnblogs.com/Clingingboy/p/1880015.html
Copyright © 2011-2022 走看看