zoukankan      html  css  js  c++  java
  • ManualResetEvent的使用与介绍

    它可以通知一个或多个正在等待的线程已发生事件,允许线程通过发信号互相通信,来控制线程是否可心访问资源

    当一个线程开始一个活动(此活动必须完成后,其他线程才能开始)时,它调用 Reset 以将 ManualResetEvent 置于非终止状态。此线程可被视为控制 ManualResetEvent。调用 ManualResetEvent 上的 WaitOne 的线程将阻止,并等待信号。当控制线程完成活动时,它调用 Set 以发出等待线程可以继续进行的信号。并释放所有等待线程。

    一旦它被终止,ManualResetEvent 将保持终止状态,直到它被手动重置。即对 WaitOne 的调用将立即返回。

    上面是它的功能描述,你可能会有点晕。我会用代码一点一点解释它,看完我写的这些内容,你自己运行一下代码你就会明白它的功能

    源代码:ManualResetEventDemo.rar

    我们从初始化来开始讲

    可以通过将布尔值传递给构造函数来控制 ManualResetEvent 的初始状态,如果初始状态处于终止状态,为 true;否则为 false。

    我用代码 让大家看一下什么是终止状态和非止状态

    先看一下代码

    class Program
       {
           static ManualResetEvent _mre = new ManualResetEvent(false);
           static void Main(string[] args)
           {
               Thread[] _threads = new Thread[3];
               for (int i = 0; i < _threads.Count(); i++)
               {
                   _threads[i] = new Thread(ThreadRun);
                   _threads[i].Start();
               }
               
           }
     
           static void ThreadRun()
           {
               int _threadID = 0;
               while (true)
               {
                   _mre.WaitOne();
                   _threadID = Thread.CurrentThread.ManagedThreadId;
                   Console.WriteLine("current Tread is " + _threadID);
                   Thread.Sleep(TimeSpan.FromSeconds(2));
                      
               }
           }
       }

    当初始化为true时,为终止状态

    static ManualResetEvent _mre = new ManualResetEvent(true);

    执行结果

     

    当初始化为false时,为非终止状态

    static ManualResetEvent _mre = new ManualResetEvent(false);

    执行结果为

    这样我们就能看出来

    终止状态时WaitOne()允许线程访问下边的语句

    非终止状态时WaitOne()阻塞线程,不允许线程访问下边的语句

    我们也可以把WaitOne()放在方法最下边

    static void ThreadRun()
            {
                int _threadID = 0;
                while (true)
                {
                     
                    _threadID = Thread.CurrentThread.ManagedThreadId;
                    Console.WriteLine("current Tread is " + _threadID);
                    Thread.Sleep(TimeSpan.FromSeconds(2));
                    _mre.WaitOne();
                }
            }

    当初始化为true时执行结果和上边的一样会不停的执行

    初始化为false时执行到waitOne()时就阻塞线程不会再往下执行了

    接下来你可能就会想当在非终止状态时怎么让线程继续执行,怎么再让它停下来,这就要用了set()和Reset()方法了

    把非终止状态改为终止状态用Set()方法

    把终止状态改为非终止状态用Reset()方法

    我用用代码来实现它们只要把我们上 边的代码做一下改动

    class Program
        {
            static ManualResetEvent _mre = new ManualResetEvent(false);
            static void Main(string[] args)
            {
                Console.WriteLine("输入1为Set()   开始运行");
                Console.WriteLine("输入2为Reset() 暂停运行");
                Thread[] _threads = new Thread[3];
                for (int i = 0; i < _threads.Count(); i++)
                {
                    _threads[i] = new Thread(ThreadRun);
                    _threads[i].Start();
                }
                while (true)
                {
                    switch (Console.ReadLine())
                    {
                        case "1":
                            _mre.Set();
                            Console.WriteLine("开始运行");
                            break;
                        case "2":
                            _mre.Reset();
                            Console.WriteLine("暂停运行");
                            break;
                        default:
                            break;
                    }
                }
                
            }
     
            static void ThreadRun()
            {
                int _threadID = 0;
                while (true)
                {
                     
                    _threadID = Thread.CurrentThread.ManagedThreadId;
                    Console.WriteLine("current Tread is " + _threadID);
                    Thread.Sleep(TimeSpan.FromSeconds(2));
                    _mre.WaitOne();
                }
            }
        }

    当输入1 时会调用 Set()方法 ManualResetEvent 处于终止状态会WaitOne不会阻塞线程会一直运行下去

    当输入2时会调用 Reser()方法ManualResetEvent处于非终止状态WaitOne会阻塞线程直到再调用 Set()方法

    看一下执行结果吧

  • 相关阅读:
    ORACLE11G 字符集更改(这里更改为AL32UTF8)
    linux 安装jdk1.8
    oracle的 listagg() WITHIN GROUP ()函数使用
    数据库事务中的隔离级别和锁以及spring @Transactional注解参数详解
    java读取Oracle中大字段数据(CLOB)的方法
    oracle常用函数_时间
    案例-todolist计划列表【添加计划】
    案例-todolist计划列表【显示列表】
    案例-todolist计划列表[基本代码]
    vue 阻止元素的默认行为
  • 原文地址:https://www.cnblogs.com/president/p/5135515.html
Copyright © 2011-2022 走看看