AutoResetEvent详解

在MSDN中,它的解释为:通知正在等待的线程已发生事件。无法继承此类(密封类)。

AutoResetEvent 允许线程通过发信号进行相互通信,例如发Set信号,让正在WaitOne等待信号着的线程开启继续执行。通常,此通信涉及线程需要独立访问的资源。

线程通过调用 AutoResetEvent 上的WaitOne来等待信号。如果 AutoResetEvent 处于非终止状态,则该线程阻塞,并等待当前控制资源的线程通过调用 Set发出资源可用的信号。

调用 Set 向 AutoResetEvent 发信号以释放等待线程,这里释放的是有WaitOne等待着的随机的某一个线程 ,而不是所有有WaitOne等待信号的线程,此时AutoResetEvent 将保持终止状态,直到一个正在等待的线程被释放,然后自动返回非终止状态。如果没有任何线程在等待(没有一个线程有WaitOne等待信号),则状态将无限期地保持为终止状态。

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

示例代码:

实现类源码:

class AutoResetEventTest
    {
        private AutoResetEvent are;

        public AutoResetEventTest()
        {
            this.are = new AutoResetEvent(false);
        }

        /// <summary>
        /// 放行等待的线程
        /// </summary>
        public void Set()
        {
            this.are.Set();
        }

        /// <summary>
        /// 暂停正在等待的线程
        /// </summary>
        public void Reset()
        {
            this.are.Reset();
        }

        /// <summary>
        /// 启动N个线程,可以手动传入参数指定启动几个线程
        /// </summary>
        /// <param name="threadNumber"></param>
        public void CreateThreads(int threadNumber)
        {
            Thread[] threads = new Thread[threadNumber];

            for (int i = 0; i < threadNumber; i++)
            {
                threads[i] = new Thread(new ThreadStart(Run));
                threads[i].Start();
            }
        }

        /// <summary>
        /// 正在等待着的线程,该线程打印出线程ID
        /// </summary>
        private void Run()
        {
            string threadId = string.Empty;
            try
            {
                while (true)
                {
                    // 阻塞当前线程
                    this.are.WaitOne();

                    threadId = Thread.CurrentThread.ManagedThreadId.ToString();
                    Console.WriteLine("Run---Thread(" + threadId + ") is running...");

                    Thread.Sleep(3000);
                }
            }
            catch (Exception ex)//异常处理
            {
                Console.WriteLine("Run---Thread(" + threadId + ") Error happend!:" + ex.Message.ToString());
            }
        }

    }

主函数源码:

在控制台界面上输入run会看到某个等待着的线程被开启:

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("**********************************");
            Console.WriteLine("请输入\"run\"开启正在等待着的线程...");
            Console.WriteLine("********************************\r\n");

            AutoResetEventTest test = new AutoResetEventTest();

            test.CreateThreads(10);

            while (true)
            {
                string input = Console.ReadLine();
                if (input.Trim().ToLower() == "run")
                {
                    Console.WriteLine("WaitOne等待着的某个线程开启运行...");
                    test.Set();
                }
            }

        }
    }

运行结果:

当输入一次run时,显示如下:

由于初始化AutoResetEvent 事件为false,则该事件处于非终止状态,故所有等待着的线程在没有Set信号到来时,都将暂停运行,当输入一次run,调用AutoResetEvent 的Set方法,将会随机开启某一个正在等待着的线程,当该等待着的线程被释放,则AutoResetEvent 自动的变为非终止状态,其余的等待线程想要开启就必须等待再一次Set信号。

当输入多次run时,显示结果如下:

每输入一次run都会调用AutoResetEvent 事件的Set方法,将会随机开启某一个正在等待着的线程,当这个线程被释放后,则AutoResetEvent  事件会自动的置为非终止状态,那么刚刚被开启的线程将会再次等待,直到等待下一次Set信号将它开启。

假如我们初始化将AutoResetEvent 事件设置为true,则在控制台下会看到如下结果:

这是因为初始化将AutoResetEvent 事件设置为true,则它会处于终止状态,那么会初次开启某个线程,当这个等待着的线程被释放时,则会自动将AutoResetEvent 设置成非终止状态,直到有Set信号给某个等待着的线程,才会开启这个等待着的线程。

如下:

再一次输入run,

调用AutoResetEvent  的Set方法,将会随机的开启某一个正在等待着的线程,线程释放完毕后会自动将AutoResetEvent 置为非终止状态,所以每当run一次只能看到一次随机等待的线程在跑

时间: 2024-07-30 10:17:11

AutoResetEvent详解的相关文章

AutoResetEvent详解(线程独占访问资源)

由来: 在学习工作流的过程中,宿主程序中会出现这么一段代码: staticAutoResetEvent instanceUnloaded = new AutoResetEvent(false); 然后就是在方法中这样使用: instanceUnloaded.Set();//将事件状态设置为终止状态,允许一个或多个等待线程继续 instanceUnloaded.WaitOne();//对于WaitOne方法为阻止当前线程,直到收到信号! 对于这部分内容当时不是很理解,下面我们先介绍一下AutoRe

AutoResetEvent和ManualResetEvent详解

AutoResetEvent 允许线程通过发信号互相通信.通常,此通信涉及线程需要独占访问的资源. 线程通过调用 AutoResetEvent 上的 WaitOne 来等待信号.如果 AutoResetEvent 处于非终止状态,则该线程阻塞,并等待当前控制资源的线程 通过调用 Set 发出资源可用的信号. 调用 Set 向 AutoResetEvent 发信号以释放等待线程.AutoResetEvent 将保持终止状态,直到一个正在等待的线程被释放,然后自动返回非终止状态.如果没有任何线程在等

Spring事务管理(详解+实例)

写这篇博客之前我首先读了<Spring in action>,之后在网上看了一些关于Spring事务管理的文章,感觉都没有讲全,这里就将书上的和网上关于事务的知识总结一下,参考的文章如下: Spring事务机制详解 Spring事务配置的五种方式 Spring中的事务管理实例详解 1 初步理解 理解事务之前,先讲一个你日常生活中最常干的事:取钱. 比如你去ATM机取1000块钱,大体有两个步骤:首先输入密码金额,银行卡扣掉1000元钱:然后ATM出1000元钱.这两个步骤必须是要么都执行要么都

转载:DenseNet算法详解

原文连接:http://blog.csdn.net/u014380165/article/details/75142664 参考连接:http://blog.csdn.net/u012938704/article/details/53468483 本文这里仅当学习笔记使用,具体细节建议前往原文细度. 论文:Densely Connected Convolutional Networks 论文链接:https://arxiv.org/pdf/1608.06993.pdf 代码的github链接:h

MariaDB(MySQL)创建、删除、选择及数据类型使用详解

一.MariaDB简介(MySQL简介略过) MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可 MariaDB的目的是完全兼容MySQL,包括API和命令行,使之能轻松成为MySQL的代替品.在存储引擎方面,使用XtraDB(英语:XtraDB)来代替MySQL的InnoDB. MariaDB由MySQL的创始人Michael Widenius(英语:Michael Widenius)主导开发,他早前曾以10亿美元的价格,将自己创建的公司MySQL A

HttpServletResponse和HttpServletRequest详解

HttpServletResponse,HttpServletRequest详解 1.相关的接口 HttpServletRequest HttpServletRequest接口最常用的方法就是获得请求中的参数,这些参数一般是客户端表单中的数据.同时,HttpServletRequest接口可以获取由客户端传送的名称,也可以获取产生请求并且接收请求的服务器端主机名及IP地址,还可以获取客户端正在使用的通信协议等信息.下表是接口HttpServletRequest的常用方法. 说明:HttpServ

POSIX 线程详解(经典必看)

总共三部分: 第一部分:POSIX 线程详解                                   Daniel Robbins ([email protected]), 总裁/CEO, Gentoo Technologies, Inc.  2000 年 7 月 01 日 第二部分:通用线程:POSIX 线程详解,第 2部分       Daniel Robbins ([email protected]), 总裁/CEO, Gentoo Technologies, Inc.  20

.NET深入解析LINQ框架(五:IQueryable、IQueryProvider接口详解)

阅读目录: 1.环路执行对象模型.碎片化执行模型(假递归式调用) 2.N层对象执行模型(纵横向对比链式扩展方法) 3.LINQ查询表达式和链式查询方法其实都是空壳子 4.详细的对象结构图(对象的执行原理) 5.IQueryable<T>与IQueryProvider一对一的关系能否改成一对多的关系 6.完整的自定义查询 1]. 环路执行对象模型.碎片化执行模型(假递归式调用) 这个主题扯的可能有点远,但是它关系着整个LINQ框架的设计结构,至少在我还没有搞懂LINQ的本意之前,在我脑海里一直频

netstat状态详解

一.生产服务器netstat tcp连接状态................................................................................ 2 1.1生产服务器某个业务LVS负载均衡上连接状态数量............................................... 2 1.2生产服务器某个业务web上连接状态数量...............................................