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


相关推荐

  • 运维必须掌握的27道Linux面试题

    运维必须掌握的27道Linux面试题1.解释下什么是GPL,GNU,自由软件?GPL:(通用公共许可证):一种授权,任何人有权取得、修改、重新发布自由软件的权力。GNU:(革奴计划):目标是创建一套完全自由、开放的的操作系统。自由软件:是一种可以不受限制地自由使用、复制、研究、修改和分发的软件。主要许可证有GPL和BSD许可证两种。 2.如何选择Linux操作系统版本?一般来讲,桌面用

  • django formview_DWG TrueView

    django formview_DWG TrueViewAPIView视图类在DRF中,推荐使用类视图,因为类视图可以通过继承的方式把一些重复性的工作抽取出来,而使得代码更加简洁。当然如果你不想使用类视图,那么就用@api_view装饰器包裹一下就可以。

  • turtle(海龟作图),C++版「建议收藏」

    turtle(海龟作图),C++版「建议收藏」海龟作图引言turtle来源Logo的原型来自另一个计算机语言LISP,派普特修改了LISP的语法使其更易于阅读。Logo常被称作没有括号的Lisp。Logo是一种解释型语言,和其他语言不同的是,它内置一套海龟绘图(TurtleGraphics)系统,通过向海龟发送命令,用户可以直观地学习程序的运行过程,因此很适于儿童学习。它亦适合用作数学教学。海龟绘图使得Logo用户可以通过简单的编程创作出丰富多彩的视觉效果或图案。假想一只带着画笔的海龟可以接受简单的命令,例如向前走100步,或者左转30度。

  • android sdk manager设置国内镜像快速下载sdk

    android sdk manager设置国内镜像快速下载sdkandroidsdkmanager通过google的url下载sdk卡成翔了,在网上找了几个国内镜像,亲测可用。AndroidSDK在线更新镜像服务器:中国科学院开源协会镜像站地址:IPV4/IPV6:http://mirrors.opencas.cn端口:80IPV4/IPV6:http://mirrors.opencas.org端口:80IPV4/IPV6:

  • 最详细AMD Ryzen CPU,VMware 15安装macOS 10.15.x Catalina 记录(第一篇)[通俗易懂]

    最详细AMD Ryzen CPU,VMware 15安装macOS 10.15.x Catalina 记录(第一篇)[通俗易懂]如何在非macOS电脑上体验macOS,目前我所知道的有两种方式:真机安装(难度大,本文介绍,感兴趣的童鞋可以自行搜索);虚拟机安装。不管是真机安装还是虚拟机安装,Intel的cpu在安装过程中遇到的坑相比AMD的cpu要少很多。所以本文不介绍如何在Intelcpu的pc上安装macOS,网上教程很多,读者可自行搜索。很多AMDcpu的朋友,在用虚拟机安装macOS的过程中,肯定遇到过一些问题,并且有些问题很棘手,会被困扰几天,那么本文将介绍如何在AMDcpu的电脑上安装mac

  • 显性与隐性URL转发替代方案[通俗易懂]

    显性与隐性URL转发替代方案[通俗易懂]本文主要介绍了特殊情况下显性与隐性URL转发替代方案。

    2022年10月19日

发表回复

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

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