AutoResetEvent和ManualResetEvent

简介:

 AutoResetEvent 就像一个十字转门,每次只允许一个取消阻塞。

static AutoResetEvent auto = new AutoResetEvent(false);

        static void Main(string[] args)
        {
            Thread t = new Thread(WaitFoSingalToWrite);
            t.Start();
            Thread.Sleep(2000);
            auto.Set();
            Console.WriteLine("Main End...");
        }
 
        static void WaitFoSingalToWrite()
        {
            Console.WriteLine("in...");
            auto.WaitOne();
            Console.WriteLine("do sth...");
            auto.WaitOne(3000);
            Console.WriteLine("do sth 1...");
            Console.WriteLine("out...");
        }
 
初始的时候,AutoResetEvent构造函数赋值false,意味着一开始就没有信号。线程t运行后遇到block。与此同时的2秒后,Main函数对auto设置了一个信号(set)。此时t可以运行下去。接下来t等待3s后继续执行直至退出。
修改代码至如下
 static AutoResetEvent auto = new AutoResetEvent( true);
        static void Main(string[] args)
        {
            Thread t = new Thread(WaitFoSingalToWrite);
            t.Start();
            Thread.Sleep(2000);
             //auto.Set();
            Console.WriteLine("Main End...");
        }
 
        static void WaitFoSingalToWrite()
        {
            Console.WriteLine("in...");
            auto.WaitOne();
            Console.WriteLine("do sth...");
            auto.WaitOne(3000);
            Console.WriteLine("do sth 1...");
            Console.WriteLine("out...");
        }
此时尽管t线程有waitone,但是由于初始就给予了一个信号,隐藏,这个block直接就运行下去了。 If Set is called when no thread is waiting, the handle stays open for as long as it takes until some thread calls WaitOne.
此处即便对多次调用set方法,但是它还是仅对下一个waitone有效,并不是调几次set方法就对几个waitone有效,多调用的set方法纯属浪费。
 static AutoResetEvent auto = new AutoResetEvent(false);
        static void Main(string[] args)
        {
            Thread t = new Thread(WaitFoSingalToWrite);
            t.Start();
            Thread.Sleep(2000);
             auto.Set();
            auto.Set();
            Console.WriteLine("Main End...");
        }
 
        static void WaitFoSingalToWrite()
        {
            Console.WriteLine("in...");
            auto.WaitOne();
            Console.WriteLine("do sth...");
            auto.WaitOne();
            Console.WriteLine("do sth1...");
           
            Console.WriteLine("out...");
        }
     此处,虽然调用了2遍,但do sth1仍然被阻塞。
 
Reset()方法将AutoResetEvent设为无信号状态,但是此方法在AutoResetEvent并没有意义,因为AutoResetEvent发完信号让线程取消阻塞后又自动设为无信号状态了。 调用waitOne(0)相当于reset了AutoResetEvent(只要AutoResetEvent是有信号状态)

 ManualResetEvent则像一个普通的门,只要有信号,所有的阻塞都能取消,直到重新Reset。

 

 static ManualResetEvent manu = new ManualResetEvent(false);
        static void Main(string[] args)
        {
            Thread t1 = new Thread(WaitFoSingalToDo);
            Thread t2 = new Thread(WaitFoSingalToPlay);
            t1.Start();
            t2.Start();
            manu.Set(); 
            Thread.Sleep(5000);
            manu.Reset(); 
            Console.WriteLine("Main End...");
        }
 
        static void WaitFoSingalToDo()
        {
            Console.WriteLine("WaitFoSingalToDo in ...");
            manu.WaitOne();
            Console.WriteLine("do sth...");
            manu.WaitOne();
            Console.WriteLine("do sth1...");
           Console.WriteLine("out...");
        }
 
 
        static void WaitFoSingalToPlay()
        {
            Console.WriteLine("WaitFoSingalToPlay in...");
            manu.WaitOne();
            Console.WriteLine("play sth...");
            
            Thread.Sleep(10000);
            manu.WaitOne();
            Console.WriteLine("play sth1...");
 
            Console.WriteLine("out...");
        }
此处,线程t1由于已经有信号,顺畅的运行完毕。t2则运行到play sth...时,等待10秒钟,而此时,5秒钟后,manu将信号Reset(),信号被取消,,所以10秒钟过后,阻塞不能通过。




















本文转自cnn23711151CTO博客,原文链接:http://blog.51cto.com/cnn237111/518814 ,如需转载请自行联系原作者
相关文章
|
Android开发
Android中实现获取相册中的图片扫描二维码的功能
Android中实现获取相册中的图片扫描二维码的功能
597 0
|
存储 人工智能 数据库
面向教育场景的大模型 RAG 检索增强解决方案
检索增强生成模型结合了信息检索与生成式人工智能的优点,从而在特定场景下提供更为精准和相关的答案。以人工智能平台 PAI 为例,为您介绍在云上使用一站式白盒化大模型应用开发平台 PAI-LangStudio 构建面向教育场景的大模型 RAG 检索增强解决方案,应用构建更简便,开发环境更直观。此外,PAI 平台同样发布了面向医疗、金融和法律领域的 RAG 解决方案。
|
Linux
模拟Linux服务器高cpu使用率
模拟Linux服务器高cpu使用率
292 1
|
人工智能 数据安全/隐私保护
图灵测试
图灵测试 “【5月更文挑战第20天】”
2952 1
|
数据采集 数据可视化 前端开发
基于python django的当当网书籍数据采集与可视化分析,实现数据采集与可视化分析,有登录注册和后台管理
本文介绍了一个基于Python和Django框架的当当网书籍数据采集与可视化分析项目,该项目实现了数据采集、用户登录注册、后台管理,并利用数据清洗、分析和可视化技术在前端展示分析结果。
460 0
基于python django的当当网书籍数据采集与可视化分析,实现数据采集与可视化分析,有登录注册和后台管理
|
Web App开发 运维 算法
软件体系结构 - 实时操作系统(Real-Time Operating System, RTOS)
【4月更文挑战第8天】软件体系结构 - 实时操作系统(Real-Time Operating System, RTOS)
1203 0
|
设计模式 前端开发 JavaScript
简述mvvm模式
简述mvvm模式
|
SQL JSON 分布式计算
数据一致性比对(番外)
我写过很多如何去对数、如何批量对数的技术文档,最近项目遇到这个问题,我才发现在官方博客上还没有发布过这个课题的文章。这就像灯下黑,太长用到的知识点,反而没有意识到其重要性。
29169 0
|
Java API 索引
Elasticsearch——使用Java API实现ES中的索引、映射、文档操作(下)
Elasticsearch——使用Java API实现ES中的索引、映射、文档操作(下)
Elasticsearch——使用Java API实现ES中的索引、映射、文档操作(下)
|
弹性计算 网络安全
如何在阿里云ECS服务器中搭建gpt-index
【1月更文挑战第6天】如何在阿里云ECS服务器中搭建gpt-index
525 0