线程 ManualResetEvent 类「建议收藏」

线程 ManualResetEvent 类「建议收藏」Reset():当一个线程开始一个活动(此活动必须完成后,其他线程才能开始)时, 它调用Reset以将ManualResetEvent置于非终止状态。此线程可被视为控制ManualResetEvent。为了把状态修改为无信号的,必须调用ReSet()方法。WaitOne():调用ManualResetEvent上的WaitOne的线程将阻止,并等待信号。  Se

大家好,又见面了,我是你们的朋友全栈君。 Reset(): 当一个线程开始一个活动(此活动必须完成后,其他线程才能开始)时, 它调用 Reset 以将 ManualResetEvent 置于非终止状态。此线程可被视为控制 ManualResetEvent。

为了把状态修改为无信号的,必须调用ReSet()方法。

WaitOne(): 调用ManualResetEvent 上的 WaitOne 的线程将阻止,并等待信号。    

Set ()当控制线程完成活动时,它调用 Set 以发出等待线程可以继续进行的信号。并释放所有等待线程。Set将事件状态设置为终止状态,允许一个或多个等待线程继续。

为了把状态修改为有信号的,必须调用Set()方法。

ManualResetEvent对象只能拥有两种状态之一:有信号(True)或无信号(false)。ManualResetEvent类继承于WaitHandle类,其构造函数的参数可确定对象的初始状态。

Set()和Reset()方法返回一个布尔值,表示是否进行了成功的修改。

 

线程 ManualResetEvent 类「建议收藏」using System;


线程 ManualResetEvent 类「建议收藏」using System.Collections.Generic;


线程 ManualResetEvent 类「建议收藏」using System.Text;


线程 ManualResetEvent 类「建议收藏」using System.Threading;


线程 ManualResetEvent 类「建议收藏」namespace ManualResetshiyan


线程 ManualResetEvent 类「建议收藏」
{

线程 ManualResetEvent 类「建议收藏」    class Program
线程 ManualResetEvent 类「建议收藏」    {

线程 ManualResetEvent 类「建议收藏」        static void Main(string[] args)
线程 ManualResetEvent 类「建议收藏」        {

线程 ManualResetEvent 类「建议收藏」            ManualResetEvent mansig;
线程 ManualResetEvent 类「建议收藏」            mansig = new ManualResetEvent(false);
线程 ManualResetEvent 类「建议收藏」            Console.WriteLine(“ManualResetEvent Before WaitOne”);
线程 ManualResetEvent 类「建议收藏」            bool b = mansig.WaitOne(1000, true);
线程 ManualResetEvent 类「建议收藏」            Console.WriteLine(“ManualResetEvent After WaitOne” + b);
线程 ManualResetEvent 类「建议收藏」            Console.ReadLine();
线程 ManualResetEvent 类「建议收藏」        }
线程 ManualResetEvent 类「建议收藏」    }
线程 ManualResetEvent 类「建议收藏」}
 

 

上面的例子中,构造了false值的ManualResetEvent对象,布尔值False把ManualResetEvent对象的初始状态设置为无信号。接着调用基类WaigHandle的WaitOne()方法。程序块在WaitOne()方法中暂停一秒,然后因为超时而退出。ManualResetEvent的状态仍然是False,因而WaitOne()返回的布尔值b是False。

下面的例子把有信号改为无信号,调用ReSet()方法,Set()方法。

[csharp] 
view plain
copy

 

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Text;  
  4. using System.Threading;  
  5. namespace 同步  
  6. {  
  7.     class Program  
  8.     {  
  9.         static void Main(string[] args)  
  10.         {  
  11.   
  12.             ManualResetEvent mansig;  
  13.             mansig = new ManualResetEvent(true);  
  14.   
  15.             bool state = mansig.WaitOne(9000, true);  
  16.             Console.WriteLine(“ManualResetEvent After WaitOne” + state);  
  17.           
  18.             mansig.Reset();  
  19.             state = mansig.WaitOne(9000, true);  
  20.             Console.WriteLine(“ManualResetEvent After WaitOne” + state);  
  21.        
  22.             mansig.Set();  
  23.             state = mansig.WaitOne(9000, true);  
  24.             Console.WriteLine(“ManualResetEvent After WaitOne” + state);  
  25.         }  
  26.     }  
  27. }   

 在ManualReset中,MnualTResetEvent对象的构造函数将其状态设置为有信号(true),结果,线程不在第一个

WaitOne()方法中等待,并返回True值。接着,ManualResetEvent对象的状态重新设置为无信号的(false),于是线程在超时之前必须等待5秒,调用Set()方法后也不用等待。

下面在看一个程序:

[csharp] 
view plain
copy

 

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Text;  
  4. using System.Threading;  
  5. namespace 同步实验  
  6. {  
  7.     class Program  
  8.     {    ///   
  9.         /// ManualResetEvent建立时是把false作为start的初始状态,这个类用于通知另一个线程,让它等待一个或多个线程。  
  10.         /// 如这个例子中,等待线程thread1线程调用mre.WaitOne(), 用于发信号的线程调用mre.Set().  
  11.         ///   
  12.         public static ManualResetEvent mre = new ManualResetEvent(false);  
  13.         public static void trmain()  
  14.         {  
  15.   
  16.             Thread tr = Thread.CurrentThread;  
  17.   
  18.             Console.WriteLine(tr.Name + ” 开始第一波等待”);  
  19.             mre.WaitOne();   //等到什么时候呢?等到mre.Set()被调用  
  20.             Console.WriteLine(tr.Name + ” 第一波启动t”);  
  21.   
  22.             mre.Reset();   //再次重置  
  23.             Console.WriteLine(tr.Name + ” 开始第二波等待”);  
  24.             mre.WaitOne();   //再次等待  
  25.             Console.WriteLine(tr.Name + ” 第二波启动”);  
  26.   
  27.             for (int x = 0; x < 10; x++)  
  28.             {  
  29.   
  30.                 Thread.Sleep(1000);  
  31.                 Console.WriteLine(tr.Name + “: ” + x);  
  32.             }  
  33.         }    
  34.   
  35.   
  36.         static void Main(string[] args)  
  37.         {  
  38.             Thread thrd1 = new Thread(new ThreadStart(trmain));  
  39.             thrd1.Name = “thread1”;  
  40.             thrd1.Start();  
  41.   
  42.             Thread thrd2 = new Thread(new ThreadStart(trmain));  
  43.             thrd2.Name = “thread2”;  
  44.             thrd2.Start();  
  45.   
  46.             for (int x = 0; x < 10; x++)  
  47.             {  
  48.                 Thread.Sleep(900);  
  49.                 Console.WriteLine(“Main :” + x);  
  50.                 if (5 == x)  
  51.                 {  
  52.                     mre.Set();   //子线程的mre.WaitOne()可以执行了。第一次等待进程  
  53.                     //;   //如果什么都不做呢,mre.Wait()那个线程就一直等在那里了?  
  54.                 }  
  55.             }  
  56.             while (thrd1.IsAlive)  
  57.             {  
  58.   
  59.                 Thread.Sleep(1000);  
  60.   
  61.                 Console.WriteLine(“Main: waiting for thread to stop…”);  
  62.                 mre.Set();   //第二次通知等待进程  
  63.             }  
  64.         }  
  65.     }  
  66.     
  67. }  

下面在看一个关于ManualResetEvent waitany的程序:

waitany一直等到有信号 才开始执行下面的语句.

[csharp] 
view plain
copy

 

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Text;  
  4. using System.Threading;  
  5. namespace 同步实验  
  6. {  
  7.     class Program  
  8.     {  
  9.         public static ManualResetEvent m_eventTemporaryTrigger;  
  10.         public static ManualResetEvent m_eventQuitTemporary;  
  11.   
  12.         private static string m_triggerParam;  
  13.   
  14.         public static void TemporaryConnThreadTrigger(String param)  
  15.         {  
  16.             m_triggerParam = param;  
  17.             m_eventTemporaryTrigger.Set();  
  18.         }  
  19.   
  20.         static void Main(string[] args)  
  21.         {  
  22.             m_eventTemporaryTrigger =new ManualResetEvent(true);  
  23.             m_eventQuitTemporary = new ManualResetEvent(true);  
  24.             //m_eventQuitTemporary = new ManualResetEvent(false);  
  25.             m_eventTemporaryTrigger.Reset(); //临时线程处于工作之中时,m_eventTemporaryTrigger始终处于被触发状态  
  26.           //  Trigger.strmain();  
  27.             WaitHandle[] events = new WaitHandle[2];  
  28.             events[0] = m_eventQuitTemporary;  
  29.             events[1] = m_eventTemporaryTrigger;  
  30.             //等待退出信号事件或触发事件  
  31.             // 返回结果:  
  32.             //     满足等待的对象的数组索引。  
  33.             int index = WaitHandle.WaitAny(events);  
  34.             Console.WriteLine(“run no wait”);  
  35.             if (index == 0)  
  36.             {
    //如果是将Main(),第三行置为false则不执行下面语句  
  37.                 Console.WriteLine(“m_eventQuitTemporary run”);  
  38.                 Console.WriteLine(m_triggerParam);  
  39.             }  
  40.         }  
  41.    }  
  42.     public class Trigger   
  43.     {  
  44.       public static void strmain()  
  45.       {  
  46.           Program.TemporaryConnThreadTrigger(“m_eventQuitTemporary run show”);  
  47.       }  
  48.     }  
  49. }  

要注意的是ManualResetEvent和AutoResetEvent 的构造函数都有一个bool的参数,用这个参数可以指定初始情况下,同步对象的处于阻塞(设置为false)还是非阻塞(设置为true)的状态。 
另外WaitOne方法也可以带两个参数: 
WaitOne (int millisecondsTimeout,bool exitContext) 
millisecondsTimeout:等待的毫秒数,或为 Timeout.Infinite (-1),表示无限期等待。 
exitContext:为 true,则等待之前先退出上下文的同步域(如果在同步上下文中),然后在稍后重新获取它;否则为false。 
就是说,等待是可以加上一个期限的,如果等待的同步对象一直都不Set()的话,那么程序就会卡死,所以在WaitOne方法里面可以放置一个时间期限,单位是毫秒。

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

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

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

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

(0)


相关推荐

  • Docker卸载_docker创建容器

    Docker卸载_docker创建容器Linux服务器Docker卸载某个镜像:首先输入命令dockerimages查看当前docker下有多少镜像:1[root@iZwz9a191mdam4di3dozk3Z~]#dockerimages2REPOSITORYTAGIMAGEIDCREATEDSIZE3mysql…

  • mysql查询前5条记录_各个数据库中,查询前n条记录的方法「建议收藏」

    mysql查询前5条记录_各个数据库中,查询前n条记录的方法「建议收藏」SQL查询前10条的方法为:1.selecttopX*fromtable_name–查询前X条记录,可以改成需要的数字,比如前10条。2.selecttopX*fromtable_nameorderbycolum_namedesc–按colum_name属性降序排序查询前X条记录,“orderby”后紧跟要排序的属性列名,其中desc表示降序,asc表示升序…

  • pycharm导入anaconda_pip怎么用镜像更新

    pycharm导入anaconda_pip怎么用镜像更新win10设置pip源在下面目录下创建pip文件夹:C:\Users\你的用户名\AppData\Roaming\pip(注意:AppData可能是隐藏文件)进入pip文件夹,新建pip.txt文件输入如下:[global]timeout=6000index-url=http://pypi.douban.com/simpletrusted-host=pypi.douban.com重命名为pip.ini,完成!!附带一些其他源:阿里云http://mi

  • gluster源码浅析

    gluster源码浅析gluster的volume是由一系列的translator组成的,translator就像输入输出流的堆栈式结构一样,由一个translator调用另一个translator,每个translator在运行时作为shared-object,根据不同的文件操作调用不同的函数.每个translator一般需要定义xlator_fops、xlator_cbks、init、fini、volume…

  • pychrome激活码2021_通用破解码

    pychrome激活码2021_通用破解码,https://javaforall.cn/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

  • C# List去重的三种方法「建议收藏」

    C# List去重的三种方法「建议收藏」三种去重的方法1、List中的元素实现IEquatabe接口,并提供Equals方法和GetHashCode方法。2、使用表达式users.Where((x,i)=>users.FindIndex(z=>z.name==x.name)==i)去重,这条语句是查找users中name等于x.name的第一个元素。经实验,这个方法效率最低。3、使用循环,判断每个元素是否重复

发表回复

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

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