详解 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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Python字符串大小比较

    Python字符串大小比较这个问题对于有编程经验的人来说,是个非常简单的问题;但是对于初学者来说,可能是个头疼的问题,所以以此记录一下。

    2022年6月21日
    44
  • SqlTransaction

    SqlTransactionpublicvoidRunSqlTransaction(stringmyConnString){   SqlConnectionmyConnection=newSqlConnection(myConnString);   myConnection.Open();   SqlCommandmyCommand=myConnection.CreateCommand();  

    2022年6月10日
    24
  • 学习vb语言「建议收藏」

    学习vb语言「建议收藏」第一天:昨天完成了安装vb环境今天大概了解了一下vb语言的一些语法,但是把所学的整理出来,一时间却又不知道如何整理。换一个方式,我来看看接下来要学什么。1.vb变量的作用域2.常用的内部函数3.数据的输入和输出4.常用的标准控件5.vb结构控制6.键盘过程7.菜单和对话栏8.数据文件学习这些的基础是今天所学的或者所了解到的1.建立一个vb程序的大致流…

    2022年6月21日
    24
  • HDU5432-Pyramid Split[通俗易懂]

    HDU5432-Pyramid Split[通俗易懂]最近以各种借口偷懒了,上次BC的题一直也没补,今天才补完第一题,非常好过,可当时就是想不通~#include#include#include#defineeps1e-5doublea[10005],b[10005];intn;intbSearch(doublebegin,doubleend,doublee){doublemid,left=begi

    2022年6月19日
    25
  • ES 安装 elasticsearch-sql插件「建议收藏」

    ES 安装 elasticsearch-sql插件「建议收藏」1、查看sql插件githubhttps://github.com/NLPchina/elasticsearch-sql2、安装1、cdelasticsearch#进入目录2、./bin/elasticsearch-plugininstallhttps://github.com/NLPchina/elasticsearch-sql/releases/download/5.4.3.0/elasticsearch-sql-5.4.3.0.zip3、下载SQL的Serverwget

    2022年6月21日
    37
  • icem二维非结构网格划分_Ansys Icem CFD网格划分实例详解PDF及附件[通俗易懂]

    icem二维非结构网格划分_Ansys Icem CFD网格划分实例详解PDF及附件[通俗易懂]网格划分是CFD仿真计算中重要的一环,icem也是Ansys家族的王牌成员,虽然现在已被mesh以及fluentmesh追赶,但是依旧是学生时代主流的追求完美结构化网格的利器!学好icem对于拓结构的理解也会更深刻!这本书没找到原版的,只有影印版,看起来不是很舒服,但是有配套视频可以学习,也算慰藉。建议买本纸质版康康,虽然纸质版也不是很清晰,因为不是彩印的,所以凑活看吧!一、书籍简介名…

    2022年5月26日
    46

发表回复

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

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