基元线程同步构造 AutoResetEvent和ManualResetEvent 线程同步
在.Net多线程编程中,AutoResetEvent和ManualResetEvent这两个类经常用到, 他们的用法很类似,但也有区别。ManualResetEvent和AutoResetEvent都可以通知一个或多个正在等待的线程已发生事件,在线程间进行同步时使用,它们都继承自EventWaitHandle。Set方法将信号置为发送状态,Reset方法将信号置为不发送状态,WaitOne等待信号的发送。可以通过构造函数的参数值来决定其初始状态,若为true则非阻塞状态,为false为阻塞状态。如果某个线程调用WaitOne方法,则当信号处于发送状态时,该线程会得到信号, 继续向下执行。其区别就在调用后,AutoResetEvent.WaitOne()每次只允许一个线程进入,当某个线程得到信号后,AutoResetEvent会自动又将信号置为不发送状态,则其他调用WaitOne的线程只有继续等待。也就是说,AutoResetEvent一次只唤醒一个线程;而ManualResetEvent则可以唤醒多个线程,因为当某个线程调用了ManualResetEvent.Set()方法后,其他调用WaitOne的线程获得信号得以继续执行,而ManualResetEvent不会自动将信号置为不发送。也就是说,除非手工调用了ManualResetEvent.Reset()方法,则ManualResetEvent将一直保持有信号状态,ManualResetEvent也就可以同时唤醒多个线程继续执行。也就是说,AutoResetEvent会在每次被Signal了之后自动(Automatically)转变为UnSignal,而ManualResetEvent则不然,无论是Signal还是UnSignal都需要人为的介入去改变它的状态。
对于它们微软是这么描述的。
ManualResetEvent
“ManualResetEvent 类表示一个本地等待处理事件,在已发事件信号后必须手动重置该事件。”“在调用 ManualResetEvent 对象的 Reset 方法之前,该对象始终保持已发信号状态。在对象保持已发信号状态期间,可以释放任意数目的等待线程或在已发事件信号后仍等待事件的线程。”
AutoResetEvent
“AutoResetEvent 类表示一个本地等待处理事件,在释放了单个等待线程以后,该事件会在终止时自动重置。”“在释放了单个等待线程以后,系统会自动将一个 AutoResetEvent 对象重置为非终止。如果没有线程在等待,事件对象的状态会保持为终止。”
我想现在应该清楚两者的区别了吧!算了,直接上例子,管你懂不懂,代码证明一切(这个例子网上可以找到底,顺手抄来懒得再写)。
你想送花给一个MM,托了一个送花的小伙子送了过去,而你希望当MM收到花之后就立即打个电话过去告诉她。但问题是你不知道花什么时候才送到MM的手里,打早了打迟了都不好,这时你可以使用ManualResetEvent对象帮忙。当委托小伙子送花过去的时候,使用ManualResetEvent的WaitOne方法进行等待。当小伙子把花送到MM的手中时,再调用一下ManualResetEvent的Set方法,你就可以准时地打电话过去了。另外ManualResetEvent还有一个Reset方法,用来重新阻断调用者执行的,情况就好比你委托了这个小伙子送花给N个MM,而又想准时地给这N个MM打电话的情况一样。
using System;
using System.Threading; public class TestMain
{
private static ManualResetEvent ent = new ManualResetEvent(false); public static void Main()
{
Boy sender = new Boy(ent);
Thread th = new Thread(new ThreadStart(sender.SendFlower));
th.Start(); ent.WaitOne(); //等待工作
Console.WriteLine("收到了吧,花是我送嘀:)");
Console.ReadLine();
} } public class Boy
{
ManualResetEvent ent; public Boy(ManualResetEvent e)
{
ent = e;
} public void SendFlower()
{
Console.WriteLine("正在送花的途中");
for (int i = ; i < ; i++)
{
Thread.Sleep();
Console.Write("..");
}
Console.WriteLine("/r/n花已经送到MM手中了,boss"); ent.Set(); //通知阻塞程序
}
}
而AutoResetEvent类故名思意,就是在每次Set完之后自动Reset。让执行程序重新进入阻塞状态。即AutoResetEvent.Set() 相当于 ManualResetEvent.Set() 之后又立即 ManualResetEvent.Reset(),其他的就没有什么不同的了。举个送花给N个MM的例子:
using System;
using System.Threading; public class TestMain
{
private static AutoResetEvent ent = new AutoResetEvent(false); public static void Main()
{
Boy sender = new Boy(ent); for (int i = ; i < ; i++)
{
Thread th = new Thread(new ThreadStart(sender.SendFlower));
th.Start();
ent.WaitOne(); //等待工作
Console.WriteLine("收到了吧,花是我送嘀:)/r/n/r/n");
} Console.ReadLine();
} } public class Boy
{
AutoResetEvent ent; public Boy(AutoResetEvent e)
{
ent = e;
} public void SendFlower()
{
Console.WriteLine("正在送花的途中");
for (int i = ; i < ; i++)
{
Thread.Sleep();
Console.Write("..");
}
Console.WriteLine("/r/n花已经送到MM手中了,boss"); ent.Set(); //通知阻塞程序,这里的效果相当于 ManualResetEvent的Set()方法+Reset()方法
}
}
注意WaitOne方法。在使用的时候注意参数millisecondsTimeout 是毫秒。这个参数最好加上,否则等待同步的对象一直不Set(),程序将无限期的等下去...
基元线程同步构造 AutoResetEvent和ManualResetEvent 线程同步的更多相关文章
- 基元用户模式构造--互锁构造 Interlocked 实现的异步web请求实例
using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using Syst ...
- 【C#进阶系列】28 基元线程同步构造
多个线程同时访问共享数据时,线程同步能防止数据损坏.之所以要强调同时,是因为线程同步问题实际上就是计时问题. 不需要线程同步是最理想的情况,因为线程同步一般很繁琐,涉及到线程同步锁的获取和释放,容易遗 ...
- 【C#】C#线程_基元线程的同步构造
目录结构: contents structure [+] 简介 为什么需要使用线程同步 线程同步的缺点 基元线程同步 什么是基元线程 基元用户模式构造和内核模式构造的比较 用户模式构造 易变构造(Vo ...
- Clr Via C#读书笔记----基元线程同步构造
线程文章:http://www.cnblogs.com/edisonchou/p/4848131.html 重点在于多个线程同时访问,保持线程的同步. 线程同步的问题: 1,线程同步比较繁琐,而且容易 ...
- 线程同步 –AutoResetEvent和ManualResetEvent
上一篇介绍了通过lock关键字和Monitor类型进行线程同步,本篇中就介绍一下通过同步句柄进行线程同步. 在Windows系统中,可以使用内核对象进行线程同步,内核对象由系统创建并维护.内核对象为内 ...
- 【C#进阶系列】29 混合线程同步构造
上一章讲了基元线程同步构造,而其它的线程同步构造都是基于这些基元线程同步构造的,并且一般都合并了用户模式和内核模式构造,我们称之为混合线程同步构造. 在没有线程竞争时,混合线程提供了基于用户模式构造所 ...
- 【C#】C#线程_混合线程的同步构造
目录结构: contents structure [+] 一个简单的混合锁 FCL中的混合锁 ManualResetEventSlim类和SemaphoreSlim类 Monitor类和同步块 Rea ...
- 读书笔记—CLR via C#同步构造28-29章节
前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可 ...
- 基元线程同步构造之waithandle中 waitone使用
在使用基元线程同步构造中waithandle中waitone方法的讲解: 调用waithandle的waitone方法阻止当前线程(提前是其状态为Nonsignaled,即红灯),直到当前的 Wait ...
随机推荐
- php中is_null,empty,isset,unset 的区别详细介绍
is_null, empty, isset, unset 我们先来看看这4个函数的描述. isset 判断变量是否已存在(配置)unset 把变量删除(释放)掉empty 判断变量是否为空is_nul ...
- JMeter--详解JMeter配置元件
JMeter配置元件可以用来初始化默认值和变量,以便后续采样器使用.将在其作用域的初始化阶段处理. CSV Data Set Config:被用来从文件中读取数据,并将它们拆分后存储到变量中,适合处理 ...
- bzoj3871: [Neerc2013 C]Cactus Automorphisms || 3899: 仙人掌树的同构
Description 给定一个N,N<=50 000个节点的仙人掌,其是指每条边最多在一个环中的无向图,求仙人掌有多少种自同构.自同构是指得是图的顶点集合V到V的变换M, 以P1^a1*P2^ ...
- Jade模板引擎使用详解
在 Express 中调用 jade 模板引擎 jade 变量调用 if 判断 循环 Case 选择 在模板中调用其他语言 可重用的 jade 块 (Mixins) 模板包含 (Includes) 模 ...
- MySQL 删除数据库的两种方法
使用 mysqladmin 删除数据库 使用普通用户登陆mysql服务器,你可能需要特定的权限来创建或者删除 MySQL 数据库. 所以我们这边使用root用户登录,root用户拥有最高权限,可以使用 ...
- redis 4,0 安装
安装redis : 1,yum install wget -y 2,cd /opt: 3,wget http://download.redis.io/releases/redis-4.0.10.tar ...
- HTML|CSS之布局相关总结
知识内容: 1.浮动相关 2.display属性 3.居中显示 4.盒模型和box-sizing 5.position属性 6.响应式设计 7.flex布局 8.其他 参考:http://zh.lea ...
- angular controller 之间的通信方式
AngularJS中的controller是个函数,用来向视图的作用域($scope)添加额外的功能,我们用它来给作用域对象设置初始状态,并添加自定义行为. 当我们在创建新的控制器时,angularJ ...
- 更新403 Forbidden
用TidHTTP下载一个文件 http://192.168.1.1/files/新建文本文档.txt 报错,但是用浏览器打开正常 HTTP/1.1 403 Forbidden 最后不是程序的问题,把i ...
- FMX TListView 搜索 Search
FMX,FireMonkey,平台框架下TListView控件搜索.过滤. 查找功能确实强大!! 设置SearchVisibe属性为true,就自动显示搜索框,输入文字,就开始检索了,不用写一行代码! ...