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个示例,展示了线程同步的问题

  • 相关阅读:
    Cocos2d-js 开发记录:图片数据资源等的异步加载
    Cocos2d-js 开发记录:声音播放
    Cocos2d-js 开发记录-初始
    PAT 1064 Complete Binary Search Tree
    python 对象属性与 getattr & setattr
    LeetCode Text Justification
    LeetCode Valid Number
    LeetCode String to Integer (atoi)
    struts2--标签取值
    java--Hibernate实现分页查询
  • 原文地址:https://www.cnblogs.com/Clingingboy/p/1880015.html
Copyright © 2011-2022 走看看