AutoResetEvent和ManualResetEvent的区别

本文深入探讨了AutoResetEvent与ManualResetEvent的区别,详细解释了它们如何在多线程环境中控制线程的阻塞与唤醒,以及在不同状态下线程的行为表现。

 

1、AutoResetEvent和ManualResetEvent的区别

  终止状态和非终止状态:
  AutoResetEvent和ManualResetEvent的构造函数中,都有bool变量来指明线程的终止状态和非终止状态。

true: 表示终止状态(个人理解也就是可运行状态,根据理解应该是该线程的阻塞终止了)
false:表示非终止状态(不可运行状态,线程的阻塞开始了)

AutoResetEvent _autoResetEvent = new AutoResetEvent(false);

private void BT_Temp_Click(object sender, RoutedEventArgs e)
{
Thread t1 = new Thread(this.Thread1Foo);
t1.Start();
Thread.Sleep(3000); //Thread.Sleep(Int32)是批当前进程挂起3000毫秒,与线程t1是一点关系也没有的。
_autoResetEvent.Set();
}

void Thread1Foo()
{
_autoResetEvent.WaitOne();
MessageBox.Show("t1 end");
}

这段代码的执行结果,就是3秒钟过后,弹出“t1 end”。

而如果把:
AutoResetEvent _autoResetEvent = new AutoResetEvent(false);//非终止状态

改为:
AutoResetEvent _autoResetEvent = new AutoResetEvent(true);//终止状态(阻塞终止)

则“t1 end”将会立刻弹出。
也就是说,在终止状态中,_autoResetEvent.WaitOne()是不会起到阻滞工作线程的作用的。
(PS:ManualResetEvent也同样)

AutoResetEvent和ManualResetEvent的区别:
AutoResetEvent 允许线程通过发信号互相通信。 通常,当线程需要独占访问资源时使用该类。

线程通过调用 AutoResetEvent 上的 WaitOne 来等待信号。
如果 AutoResetEvent 为非终止状态,则线程会被阻止,并等待当前控制资源的线程通过调用 Set来通知资源可用。

调用 Set 向 AutoResetEvent 发信号以释放等待线程。
AutoResetEvent 将保持终止状态,直到一个正在等待的线程被释放,然后自动返回非终止状态。 如果没有任何线程在等待,则状态将无限期地保持为终止状态。
如果当 AutoResetEvent 为终止状态时线程调用 WaitOne,则线程不会被阻止。
AutoResetEvent 将立即释放线程并返回到非终止状态。

AutoResetEvent只会给一个线程发送信号,而不会给多个线程发送信号。
需要同步多个线程的时候,就只能采用ManualResetEvent了。至于深层次的原因是,AutoResetEvent在set()之后,会将线程 状态自动置为false,而ManualResetEvent在Set()后,线程的状态就变为true了,必须手动ReSet()之后,才会重新将线程置为false。这也就是为什么他们的名字一个为Auto,一个为Manual的原因。

ManualResetEvent _menuRestEvent = new ManualResetEvent(false);

private void BT_Temp_Click(object sender, RoutedEventArgs e)
{
Thread t1 = new Thread(this.Thread1Foo);
t1.Start();
Thread t2 = new Thread(this.Thread2Foo);
t2.Start();
Thread.Sleep(3000);
_menuRestEvent.Set();
//_menuRestEvent.Reset();
}

void Thread1Foo()
{
_menuRestEvent.WaitOne();
MessageBox.Show("t1 step1 end");

//睡1S,用于等待主线程_menuRestEvent.Reset();
Thread.Sleep(1000);
_menuRestEvent.WaitOne();
MessageBox.Show("t1 step2 end");
}

void Thread2Foo()
{
_menuRestEvent.WaitOne();
MessageBox.Show("t2 step1 end");
//睡1S,用于等待主线程_menuRestEvent.Reset();
Thread.Sleep(1000);
_menuRestEvent.WaitOne();
MessageBox.Show("t2 step2 end");
}
我们对//_menuRestEvent.Reset()进行了注释,也就是说, _menuRestEvent.Set()后,线程的状态就是true状态的,程序运行的结果是"t1 step1 end"、"t1 step2 end"、"t1 step2 end"、"t2 step2 end"在3秒之后全部弹出。
而如果我们将//_menuRestEvent.Reset()的注释去掉,会发现"t1 step2 end"和"t2 step2 end"永远不会弹出。除非我们在主线程中再次对_menuRestEvent进行Set()。

_manualResetEvent .Set();的这句话我想大家都明白了,可以看做将IsRelease的属性设置为true.线程1中

_manualResetEvent.WaitOne();接收到信号后不再阻塞线程1。在此之后的整个过程中IsRelease的值都是true.如果

想将IsRelease的值回复成false,就必须再调用_manualResetEvent.Reset()的方法。

如果是_autoResetEvent.set(),那么_autoResetEvent.WaitOne()后会自动将IsRelease的值自动设置为false。

转载于:https://www.cnblogs.com/lusheng320520/p/10836396.html

乐播投屏是一款简单好用、功能强大的专业投屏软件,支持手机投屏电视、手机投电脑、电脑投电视等多种投屏方式。 多端兼容与跨网投屏:支持手机、平板、电脑等多种设备之间的自由组合投屏,且无需连接 WiFi,通过跨屏技术打破网络限制,扫一扫即可投屏。 广泛的应用支持:支持 10000+APP 投屏,包括综合视频、网盘与浏览器、美韩剧、斗鱼、虎牙等直播平台,还能将央视、湖南卫视等各大卫视的直播内容一键投屏。 高清流畅投屏体验:腾讯独家智能音画调校技术,支持 4K 高清画质、240Hz 超高帧率,低延迟不卡顿,能为用户提供更高清、流畅的视觉享受。 会议办公功能强大:拥有全球唯一的 “超级投屏空间”,扫码即投,无需安装。支持多人共享投屏、远程协作批注,PPT、Excel、视频等文件都能流畅展示,还具备企业级安全加密,保障会议资料不泄露。 多人互动功能:支持多人投屏,邀请好友加入投屏互动,远程也可加入。同时具备一屏多显、语音互动功能,支持多人连麦,实时语音交流。 文件支持全面:支持 PPT、PDF、Word、Excel 等办公文件,以及视频、图片等多种类型文件的投屏,还支持网盘直投,无需下载转格式。 特色功能丰富:投屏时可同步录制投屏画面,部分版本还支持通过触控屏或电视端外接鼠标反控电脑,以及在投屏过程中用画笔实时标注等功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值