ManualResetEvent 与 AutoResetEvent 的理解和使用

摘要:
在多线程开发中,时常用到ManualResetEvent与AutoResetEvent。它们如同道路交通中的信号灯。两者之间有什么区别呢?添加到短语集没有此单词集:罗马尼亚语→...创建新的单词集...拷贝

在多线程开发中,时常用到ManualResetEvent 与AutoResetEvent 。 它们如同道路交通中的信号灯。两者之间有什么区别呢?

共同点:

均继承EventWaitHandle 接口,因此,均具有以下功能:

Reset() //红灯

Set() //绿灯

WaitOne() // 等待信号

ManualResetEvent mre = new ManualResetEvent(false);红灯

AutoResetEventauto = new ManualResetEvent(false);红灯

不同点:

AutoResetEvent 收到 Set 后 , 一次只能执行一个线程,其它线程继续 WaitOne 。

ManualResetEvent 收到 Set 后,所有处理 WaitOne 状态线程均继续执行

classProgram
    {
        static void Main(string[] args)
        {
            //注意:ManualResetEvent可以对所有进行等待的线程进行统一控制
 
            //true-初始状态为发出信号;false-初始状态为未发出信号
            ManualResetEvent mre = new ManualResetEvent(false);
            //线程池开启10个线程
            for (int i = 0; i < 10; i++)
            {
                int k =i;
                
                ThreadPool.QueueUserWorkItem(t =>{
                    Console.WriteLine($"这是第{k+1}个线程,线程ID为{Thread.CurrentThread.ManagedThreadId}");
                    //等待信号,没有信号的话不会执行后面的语句,因为初始状态是false,所以后面的语句暂时不会执行
mre.WaitOne();
                    Console.WriteLine($"第{k+1}个线程获得信号,线程ID为{Thread.CurrentThread.ManagedThreadId}");
                });
            }
            Thread.Sleep(5000);
            Console.WriteLine("
 5秒后发出信号... 
");
            //Set()方法:释放信号,所有等待信号的线程都将获得信号,开始执行WaitOne()后面的语句
mre.Set();
            Console.ReadKey();
        }
    }

执行结果如图

ManualResetEvent 与 AutoResetEvent 的理解和使用第1张

可见,没有信号时,WaitOne()后面的语句都不执行(被阻塞),当Set()释放信号后,所有阻塞的线程都开始继续执行。

  • 添加到短语集
    • 没有此单词集:罗马尼亚语 → ...
    • 创建新的单词集...
  • 拷贝

免责声明:文章转载自《ManualResetEvent 与 AutoResetEvent 的理解和使用》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇ios-极光推送sdk使用ansible api2.0 多进程执行不同的playbook下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

由浅入深TheradLocal

线程并发:在多线程并发的场景下 传递数据:我们可以通过ThreadLocal在同一线程,不同组件中传递公共变量 线程隔离:每个线程的变量都是独立的,不会相互影响 常用方法 方法声明 描述 ThreadLocal() 创建ThreadLocal对象 public void set(T value) 设置当前线程绑定的局部变量 public...

apache安装时的一些术语

apache源码安装时,需要的哪些必须依赖模块? 主要需要apr, apr-util, pcre模块其中 apr模块时必须的. 如何卸载 源码安装的软件? 在源码 的 解压目录下, 使用 make uninstall/ make clean, make distclean 直接将 安装在--prefix目录下的文件全部都删除掉即可! 使用 --prefi...

【数据库开发】数据库连接池及其工作原理

对于一个简单的数据库应用,由于对于数据库的访问不是很频繁。这时可以简单地在需要访问数据库时,就新创建一个连接,用完后就关闭它,这样做也不会带来什么明显的性能上的开销。但是对于一个复杂的数据库应用,情况就完全不同了。频繁的建立、关闭连接,会极大的减低系统的性能,因为对于连接的使用成了系统性能的瓶颈。 连接复用。通过建立一个数据库连接池以及一套连接使用管理...

(转)Netty : writeAndFlush的线程安全及并发问题

rocketmq用netty实现的网络连接,发现它多个线程掉用一个channel连接,所以这个是线程安全的? 使用Netty编程时,我们经常会从用户线程,而不是Netty线程池发起write操作,因为我们不能在netty的事件回调中做大量耗时操作。那么问题来了 – 1, writeAndFlush是线程安全的吗? 2, 是否使用了锁,导致并发性能下降呢 我...

数据库连接池SQLAlchemy中多线程安全问题

数据库连接池SQLAlchemy中多线程安全的问题 1、数据库模块model.py from sqlalchemy.orm import scoped_session from sqlalchemy.orm import sessionmaker session_factory = sessionmaker(bind=some_engine) Ses...

多线程编程5种方法实现线程同步

1:用Interlocked系列函数实现线程同步; 2:用CRITICAL_SECTION及其系列函数实现线程同步; 3:用RTL_SRWLOCK及其系列函数实现线程同步; 4:用事件内核对象实现线程同步; 5:用信号量内核对象实现线程同步;   1:用Interlocked系列函数实现线程同步实例如下: //旋转锁 #include <iostre...