C#多线程(7):手动线程通知
区别与示例
AutoResetEvent 和 ManualResetEvent 十分相似。两者之间的区别,在于前者是自动(Auto),后者是手动(Manua)。
你可以先运行下面的示例,再测试两者的区别。
AutoResetEvent 示例:
class Program
{
// 线程通知
private static AutoResetEvent resetEvent = new AutoResetEvent(false);
static void Main(string[] args)
{
// 创建线程
new Thread(DoOne).Start();
// 用于不断向另一个线程发送信号
while (true)
{
Console.ReadKey();
resetEvent.Set(); // 发生通知,设置终止状态
}
}
public static void DoOne()
{
Console.WriteLine("① 等待中,请发出信号允许我运行");
resetEvent.WaitOne();
Console.WriteLine("② 等待中,请发出信号允许我运行");
resetEvent.WaitOne();
Console.WriteLine("③ 等待中,请发出信号允许我运行");
// ...
Console.WriteLine("线程结束");
}
}
ManualResetEvent 类示例:
class Program
{
private static ManualResetEvent resetEvent = new ManualResetEvent(false);
static void Main(string[] args)
{
new Thread(DoOne).Start();
// 用于不断向另一个线程发送信号
while (true)
{
Console.ReadKey();
resetEvent.Set(); // 发生通知,设置终止状态
}
}
public static void DoOne()
{
Console.WriteLine("等待中,请发出信号允许我运行");
resetEvent.WaitOne();
// 后面的都无效,线程会直接跳过而无需等待
resetEvent.WaitOne();
resetEvent.WaitOne();
resetEvent.WaitOne();
resetEvent.WaitOne();
resetEvent.WaitOne();
Console.WriteLine("线程结束");
}
}
因为 AutoResetEvent 对象在 .WaitOne() 方法等待信号完毕后,会自动重置为非终止状态,相当于高速收费站自动闸门,一辆车过去后,机器自动关闸。
ManualResetEvent 相当于人工闸门,打开后编写人工关闭闸门,不然的话闸门会一直处于打开状态。
ManualResetEvent 主要用于更加灵活的线程信号传递场景。
ManualResetEvent 类
表示线程同步事件,收到信号时,要想下一次依然生效,必须手动重置该事件。
因为 ManualResetEvent 类跟 AutoManualResetEvent 类十分接近,这里就不赘述了。
它们的使用区别主要是:
AutoResetEvent 类,每次 Set() ,跳过一个 WaitOne()。因为会 自动恢复设置,所以下次碰到 WaitOne() 会继续等待。
ManualResetEvent 类, Set() 后,不会重置设置,因此一旦使用了 Set() 后,就会一路放通,不会再等待。
其构造函数如下:
| 构造函数 | 说明 |
|---|---|
| ManualResetEvent(Boolean) | 用一个指示是否将初始状态设置为终止的布尔值初始化 ManualResetEvent 类的新实例。 |
其常用方法如下:
| 方法 | 说明 |
|---|---|
| Close() | 释放由当前 WaitHandle 占用的所有资源。 |
| Reset() | 将事件状态设置为非终止,从而导致线程受阻。 |
| Set() | 将事件状态设置为有信号,从而允许一个或多个等待线程继续执行。 |
| WaitOne() | 阻止当前线程,直到当前 WaitHandle 收到信号。 |
| WaitOne(Int32) | 阻止当前线程,直到当前 WaitHandle 收到信号,同时使用 32 位带符号整数指定时间间隔(以毫秒为单位)。 |
| WaitOne(Int32, Boolean) | 阻止当前线程,直到当前的 WaitHandle 收到信号为止,同时使用 32 位带符号整数指定时间间隔,并指定是否在等待之前退出同步域。 |
| WaitOne(TimeSpan) | 阻止当前线程,直到当前实例收到信号,同时使用 TimeSpan 指定时间间隔。 |
| WaitOne(TimeSpan, Boolean) | 阻止当前线程,直到当前实例收到信号为止,同时使用 TimeSpan 指定时间间隔,并指定是否在等待之前退出同步域。 |
ManualResetEventSlim
ManualResetEventSlim 相对 ManualResetEvent ,当等待时间预计非常短并且事件不跨越进程边界时,可以使用此类来获得比 ManualResetEvent 更好的性能。
从代码使用来看,没有啥区别,主要就是考虑性能下时,两者不同场景。
这里就不对这两个类型赘述了。
C#多线程(7):手动线程通知的更多相关文章
- C#多线程(6):线程通知
目录 AutoRestEvent 类 常用方法 一个简单的示例 解释一下 复杂一点的示例 解释 回顾一下,前面 lock.Monitor 部分我们学习了线程锁,Mutex 部分学习了进程同步,Sema ...
- 20190102(多线程,守护线程,线程互斥锁,信号量,JoinableQueue)
多线程 多进程: 核心是多道技术,本质上就是切换加保存技术. 当进程IO操作较多,可以提高程序效率. 每个进程都默认有一条主线程. 多线程: 程序的执行线路,相当于一条流水线,其包含了程序的具体执行步 ...
- .NET面试题解析(07)-多线程编程与线程同步
系列文章目录地址: .NET面试题解析(00)-开篇来谈谈面试 & 系列文章索引 关于线程的知识点其实是很多的,比如多线程编程.线程上下文.异步编程.线程同步构造.GUI的跨线程访问等等, ...
- .NET面试题解析(07)-多线程编程与线程同步 (转)
http://www.cnblogs.com/anding/p/5301754.html 系列文章目录地址: .NET面试题解析(00)-开篇来谈谈面试 & 系列文章索引 关于线程的知识点其实 ...
- C#学习笔记之线程 - 通知Signal
通知事件等待句柄 Signal With EventWaitHandle 事件等待句柄常用于通知.当一个线程等待直到接收到另外一个线程发出的信号.事件等待句柄是最简单的信号结构,它与C#事件无关.有三 ...
- VC中利用多线程技术实现线程之间的通信
当前流行的Windows操作系统能同时运行几个程序(独立运行的程序又称之为进程),对于同一个程序,它又可以分成若干个独立的执行流,我们称之为线程,线程提供了多任务处理的能力.用进程和线程的观点来研究软 ...
- -1-5 java 多线程 概念 进程 线程区别联系 java创建线程方式 线程组 线程池概念 线程安全 同步 同步代码块 Lock锁 sleep()和wait()方法的区别 为什么wait(),notify(),notifyAll()等方法都定义在Object类中
本文关键词: java 多线程 概念 进程 线程区别联系 java创建线程方式 线程组 线程池概念 线程安全 同步 同步代码块 Lock锁 sleep()和wait()方法的区别 为什么wait( ...
- Python中的多线程编程,线程安全与锁(二)
在我的上篇博文Python中的多线程编程,线程安全与锁(一)中,我们熟悉了多线程编程与线程安全相关重要概念, Threading.Lock实现互斥锁的简单示例,两种死锁(迭代死锁和互相等待死锁)情况及 ...
- 转:java多线程CountDownLatch及线程池ThreadPoolExecutor/ExecutorService使用示例
java多线程CountDownLatch及线程池ThreadPoolExecutor/ExecutorService使用示例 1.CountDownLatch:一个同步工具类,它允许一个或多个线程一 ...
- Java多线程并发02——线程的生命周期与常用方法,你都掌握了吗
在上一章,为大家介绍了线程的一些基础知识,线程的创建与终止.本期将为各位带来线程的生命周期与常用方法.关注我的公众号「Java面典」了解更多 Java 相关知识点. 线程生命周期 一个线程不是被创建了 ...
随机推荐
- 买彩票能中大奖?用Java盘点常见的概率悖论 | 京东云技术团队
引言 <双色球头奖概率与被雷劈中的概率哪个高?> <3人轮流射击,枪法最差的反而更容易活下来?> 让我们用Java来探索ta们! 悖论1:著名的三门问题 规则描述:你正在参加一 ...
- SPI在Java中的实现与应用 | 京东物流技术团队
1 SPI的概念 API API在我们日常开发工作中是比较直观可以看到的,比如在 Spring 项目中,我们通常习惯在写 service 层代码前,添加一个接口层,对于 service 的调用一般也都 ...
- 2024-01-27:用go语言,阿里巴巴走进了装满宝藏的藏宝洞。藏宝洞里面有N堆金币, 第i堆金币的总重量和总价值分别是m[i]、v[i], 阿里巴巴有一个承重量为T的背包,但并不一定有办法将全部的
2024-01-27:用go语言,阿里巴巴走进了装满宝藏的藏宝洞.藏宝洞里面有N堆金币, 第i堆金币的总重量和总价值分别是m[i].v[i], 阿里巴巴有一个承重量为T的背包,但并不一定有办法将全部的 ...
- C# await和Result对比
1.Result 上图是微软官网的截图,由图可知在使用GetXXXX的方法的时候,会阻塞调用其他线程,直到当前异步操作完成,相当于调用wait方法.但是使用异步编程应该避免使用TASK.WAIT或TA ...
- 字节码编程,Javassist篇五《使用Bytecode指令码生成含有自定义注解的类和方法》
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 到本章为止已经写了四篇关于字节码编程的内容,涉及了大部分的API方法.整体来说对 J ...
- list集合去重_谈谈Java中Set集合去重的原理
导读:Java中Set接口是Collectio的子接口,Set集合不允许包含相同的元素.如果添加相同的元素, add()会返回FALSE, 新元素不会加入.Set集合常用于元素为数字.字符串去重等,但 ...
- 《ASP.NET Core 微服务实战》-- 读书笔记(第5章)
第 5 章 创建数据服务 选择一种数据存储 由于我坚持要尽可能的跨平台,所以我决定选用 Postgres,而不用 SQL Server 以照顾 Linux 或 Mac 电脑的读者 构建 Postgre ...
- 2023年多校联训NOIP层测试2
2023年多校联训NOIP层测试2 爆零了 T1 HDU 4786 Fibonacci Tree \(0pts\) @wangyunbiao: 不可以,总司令 我:不,可以,总司令 @wangyunb ...
- 反悔贪心&模拟费用流
贪心是一种常用的算法,它能够获得局部最优解,但我们往往需要的是全局最优解,所以我们在贪心的时候加入和反悔的机制,让他能够得到全局最优解. 由于网络流中的退流操作本质上也是反悔贪心,所以在实现反悔贪心时 ...
- NC20189 [JSOI2011]分特产
题目链接 题目 题目描述 JYY 带队参加了若干场ACM/ICPC 比赛,带回了许多土特产,要分给实验室的同学们. JYY 想知道,把这些特产分给N 个同学,一共有多少种不同的分法? 当然,JYY 不 ...