详解 ManualResetEvent(转)

详解 ManualResetEvent(转)原文:http://www.cnblogs.com/li-peng/p/3291306.html今天详细说一下ManualResetEvent它可以通知一个或多个正在等待的线程已发生事件,允许线程通过发信号互相通信,来控制线程是否可心访问资源当一个线程开始一个活动(此活动必须完成后,其他线程才能开始)时,它调用Reset以将ManualResetEvent置于非终止状…

大家好,又见面了,我是你们的朋友全栈君。

原文:http://www.cnblogs.com/li-peng/p/3291306.html

今天详细说一下ManualResetEvent

它可以通知一个或多个正在等待的线程已发生事件,允许线程通过发信号互相通信,来控制线程是否可心访问资源

当一个线程开始一个活动(此活动必须完成后,其他线程才能开始)时,它调用 Reset 以将 ManualResetEvent 置于非终止状态。此线程可被视为控制 ManualResetEvent。调用 ManualResetEvent 上的WaitOne 的线程将阻止,并等待信号。当控制线程完成活动时,它调用 Set 以发出等待线程可以继续进行的信号。并释放所有等待线程。

一旦它被终止,ManualResetEvent 将保持终止状态,直到它被手动重置。即对 WaitOne 的调用将立即返回。

上面是它的功能描述,你可能会有点晕。我会用代码一点一点解释它,看完我写的这些内容,你自己运行一下代码你就会明白它的功能

源代码:ManualResetEventDemo.rar

我们从初始化来开始讲

可以通过将布尔值传递给构造函数来控制 ManualResetEvent 的初始状态,如果初始状态处于终止状态,为 true;否则为 false。

我用代码 让大家看一下什么是终止状态和非终止状态

先看一下代码

class 
Program
   
{
       
static 
ManualResetEvent _mre =
new 
ManualResetEvent(
false
);
       
static 
void 
Main(
string
[] args)
       
{
           
Thread[] _threads =
new 
Thread[3];
           
for 
(
int 
i = 0; i < _threads.Count(); i++)
           
{
               
_threads[i] =
new 
Thread(ThreadRun);
               
_threads[i].Start();
           
}
           
       
}
 
       
static 
void 
ThreadRun()
       
{
           
int 
_threadID = 0;
           
while 
(
true
)
           
{
               
_mre.WaitOne();
               
_threadID = Thread.CurrentThread.ManagedThreadId;
               
Console.WriteLine(
"current Tread is " 
+ _threadID);
               
Thread.Sleep(TimeSpan.FromSeconds(2));
                  
           
}
       
}
   
}

当初始化为true时,为终止状态

static 
ManualResetEvent _mre =
new 
ManualResetEvent(
true
);

执行结果

 详解 ManualResetEvent(转)

当初始化为false时,为非终止状态

static 
ManualResetEvent _mre =
new 
ManualResetEvent(
false
);

执行结果为

详解 ManualResetEvent(转)

这样我们就能看出来

终止状态时WaitOne()允许线程访问下边的语句

非终止状态时WaitOne()阻塞线程,不允许线程访问下边的语句

我们也可以把WaitOne()放在方法最下边

static 
void 
ThreadRun()
        
{
            
int 
_threadID = 0;
            
while 
(
true
)
            
{
                 
                
_threadID = Thread.CurrentThread.ManagedThreadId;
                
Console.WriteLine(
"current Tread is " 
+ _threadID);
                
Thread.Sleep(TimeSpan.FromSeconds(2));
                
_mre.WaitOne();
            
}
        
}

当初始化为true时执行结果和上边的一样会不停的执行

详解 ManualResetEvent(转)

初始化为false时执行到waitOne()时就阻塞线程不会再往下执行了

详解 ManualResetEvent(转)

接下来你可能就会想当在非终止状态时怎么让线程继续执行,怎么再让它停下来,这就要用了set()和Reset()方法了

把非终止状态改为终止状态用Set()方法

把终止状态改为非终止状态用Reset()方法

我用用代码来实现它们只要把我们上 边的代码做一下改动

class 
Program
    
{
        
static 
ManualResetEvent _mre =
new 
ManualResetEvent(
false
);
        
static 
void 
Main(
string
[] args)
        
{
            
Console.WriteLine(
"输入1为Set()   开始运行"
);
            
Console.WriteLine(
"输入2为Reset() 暂停运行"
);
            
Thread[] _threads =
new 
Thread[3];
            
for 
(
int 
i = 0; i < _threads.Count(); i++)
            
{
                
_threads[i] =
new 
Thread(ThreadRun);
                
_threads[i].Start();
            
}
            
while 
(
true
)
            
{
                
switch 
(Console.ReadLine())
                
{
                    
case 
"1"
:
                        
_mre.Set();
                        
Console.WriteLine(
"开始运行"
);
                        
break
;
                    
case 
"2"
:
                        
_mre.Reset();
                        
Console.WriteLine(
"暂停运行"
);
                        
break
;
                    
default
:
                        
break
;
                
}
            
}
            
        
}
 
        
static 
void 
ThreadRun()
        
{
            
int 
_threadID = 0;
            
while 
(
true
)
            
{
                 
                
_threadID = Thread.CurrentThread.ManagedThreadId;
                
Console.WriteLine(
"current Tread is " 
+ _threadID);
                
Thread.Sleep(TimeSpan.FromSeconds(2));
                
_mre.WaitOne();
            
}
        
}
    
}

 

 

当输入1 时会调用 Set()方法 ManualResetEvent 处于终止状态会WaitOne不会阻塞线程会一直运行下去

当输入2时会调用 Reser()方法ManualResetEvent处于非终止状态WaitOne会阻塞线程直到再调用 Set()方法

看一下执行结果吧

详解 ManualResetEvent(转)

 代码:ManualResetEventDemo.rar

转载于:https://www.cnblogs.com/wwwbdabc/p/10333569.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/161178.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Promise的使用方法[通俗易懂]

    Promise的使用方法[通俗易懂]PS~:Promise是一个构造函数,自己身上有all、reject、resolve等几个方法,原型上有then、catch等几个方法。Promise对象用于表示一个异步操作的最终状态(完成或失败),以及其返回的值。一、Promise有以下三种状态:pending:初始状态,既不是成功,也不是失败状态,(等待中,或者进行中,表示还没有得到结果)fulfi…

    2022年10月24日
  • Java正则匹配空格_js正则表达式匹配空格

    Java正则匹配空格_js正则表达式匹配空格需求针对tab键带来的多个空格问题,有时候我们针对带空格的一行数据要进行切割,如果有多个空格就会出现就会切割空格出现,我们想把空格都去掉,所以需要用到某些方法。解决方案利用正则表达式来匹配空格\\s+首先利用split(“\\s+”);方法来对字符串切割,尽可能的匹配空格,这里也挺有意思,因为空格数目不一样,可以动态变换匹配的空格数量,这个实现原理可以看看底层原理,挺有意思。测试:

    2022年9月24日
  • 简易漫画网站搭建-漫画喵Server版

    简易漫画网站搭建-漫画喵Server版本文实现了一个简单的个人漫画网站,配合之前的漫画爬虫使用。享受无处不在的漫画生活。github地址:https://github.com/miaoerduo/cartoon-cat-server

    2022年8月4日
  • Tomcat之——宕机自动重启和每日定时启动tomcat

    Tomcat之——宕机自动重启和每日定时启动tomcat在项目后期维护中会遇到这样的情况,tomcat在内存溢出的时候就出现死机的情况和遇到长时间不响应,需要人工手动关闭和重启服务,针对这样的突发情况,希望程序能自动处理问题而不需要人工关于,所以才有了目前的需求。一、设置tomcat定时启动1,首先将tomcat注册为服务,先打开tomcat的bin目录下service.bat文件,修改下面的值,这是sevvice的注册名称和显示名称,一般

    2022年7月23日
  • Liquibase的简单使用[通俗易懂]

    Liquibase的简单使用[通俗易懂]`LiquiBase`是一个用于数据库重构和迁移的开源工具,通过日志文件的形式记录数据库的变更,然后执行日志文件中的修改,将数据库更新或回滚到一致的状态。它的目标是提供一种数据库类型无关的解决方案,通

    2022年8月5日
  • 永恒之蓝是谁激活成功教程的_永恒之蓝病毒激活成功教程了吗

    永恒之蓝是谁激活成功教程的_永恒之蓝病毒激活成功教程了吗简介:NSA武器库的公开被称为是网络世界“核弹危机”,其中有十款影响Windows个人用户的黑客工具,包括永恒之蓝、永恒王者、永恒浪漫、永恒协作、翡翠纤维、古怪地鼠、爱斯基摩卷、文雅学者、日食之翼和尊重审查。这些工具能够远程攻破全球约70%的Windows系统,无需用户任何操作,只要联网就可以入侵电脑,就像冲击波、震荡波等著名蠕虫一样可以瞬间血洗互联网,木马黑产很可能改造NSA的武器…

    2022年10月29日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号