详解 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

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • linux 同步北京时间 局域网同步时间

    linux 同步北京时间 局域网同步时间如果不是北京时间先改成北京时间1.删除自带的localtimerm-rf/etc/localtime2.创建软链接到localtimeln-s/usr/share/zoneinfo/Asia/Shanghai/etc/localtime在同步时间方法一:使用ntpdate比较简单安装ntpdateyuminstallntpdatentpdate…

  • Thread的join方法[通俗易懂]

    Thread的join方法[通俗易懂]Thread中的join方法主要的作用是让jion的线程加入当前线程,等加入的线程执行完之后才会执行当前线程。接下来看个例子:publicclassTestJoin{publicstaticvoidmain(String[]args)throwsInterruptedException{Threadt1=newThread(()->{try{Thr

  • 怎样用Java编写一段代码引发内存泄露

    怎样用Java编写一段代码引发内存泄露

    2021年12月10日
  • 东软始业教育内容提纲(2020)(后附题目)

    东软始业教育内容提纲(2020)(后附题目)东软始业教育内容提纲(后附题目)——2012年8月修正版写在前面:至各位兄弟姐妹,希望大家都能顺利通过!有些题目略微有些变动,总体内容不变。后面的题目绝大多数都在列了,剩余的注意搜索关键字,在前面提纲部分一定有!在百度上搜索一次只能搜索三页,建议大家先下载下来,准备好再开始考试,这样可以全篇搜索。40分的极致不是我的追求,38分这个绝对可以有!1)

  • C++int转char型并存入char数组「建议收藏」

    C++int转char型并存入char数组「建议收藏」只需在赋值语句后面加上‘0’,如下:inta=10;chara[10];a[1]=a+’0′;

  • esp8266架构_esp8266能做什么

    esp8266架构_esp8266能做什么    欢迎大家来到ESP8266的世界,从现在开始,笔者将带领大家慢慢揭开ESP8266神秘的面纱。1.简介    从笔者的角度来说,ESP8266这个词可以理解为ESP8266EX芯片(当然,后面也有可能出现了其他芯片,这里首推ESP8266EX)以及依赖ESP8266EX芯片开发的系列模组的简称。    ESP8266EX是由乐鑫信息科技公司(Espressif)出品的一款应用于物联…

发表回复

您的电子邮箱地址不会被公开。

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