ManualResetEvent类的用法

ManualResetEvent类的用法ManualResetEvent类作用1.事件初始状态设为false,task线程在第一个WaitOne()处阻塞。2.manualResetEvent.Set()事件状态设为true,task线程在每一个WaitOne()处都不阻塞。3.manualResetEvent调用Set()再调用Reset(),task线程在第一个WaitOne()处阻塞。4.manualResetEvent.Set()事件状态设为true,task线程在第一个WaitOne()处阻塞然后被释放。5.三个线程异步执行,set()

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


在这里插入图片描述

#作用

一个线程通知其他一个或多个线程正在发送的事件。

ManualResetEvent manualResetEvent = new ManualResetEvent(false);

参数表示调用WaitOne()方法的线程是继续执行(true)还是阻塞(false)。

WaitOne():调用WaitOne()方法的线程会阻塞,等待主控线程的manualResetEvent.Set()信号。

Set():将事件状态设为true,调用WaitOne()的线程继续执行。
Reset():将事件状态设为false,调用WaitOne()的线程阻塞。

Set() Reset():只针对WaitOne()方法,不影响WaitOne()方法之前的程序执行。若没有信号,调用WaitOne()方法的线程一直阻塞。

1.事件初始状态设为false,task线程在第一个WaitOne()处阻塞。

using System;
using System.Threading;
using System.Threading.Tasks;
namespace ManualResetEvent测试
{ 
   
    class Program
    { 
   
        static ManualResetEvent manualResetEvent = new ManualResetEvent(false);

        static void Main(string[] args)
        { 
   
            //Task线程和主线程同时执行
            Task task = Task.Factory.StartNew(() =>
            { 
   
                GetDataFromServer(1);
            });
            Console.ReadLine();
        }

        static void GetDataFromServer(int serverNumber)
        { 
   
            Console.WriteLine("I get first data from server" + serverNumber);
            manualResetEvent.WaitOne();
            Console.WriteLine("I get second data from server" + serverNumber);
            Thread.Sleep(TimeSpan.FromSeconds(2));
            Console.WriteLine("I get third data from server" + serverNumber);
            manualResetEvent.WaitOne();
            Console.WriteLine("All the data collected from server" + serverNumber);
        }
    }
}

输出:
I get first data from server1

2.manualResetEvent.Set()事件状态设为true,task线程在每一个WaitOne()处都不阻塞。

namespace ManualResetEvent测试
{ 
   
    class Program
    { 
   
        static ManualResetEvent manualResetEvent = new ManualResetEvent(false);

        static void Main(string[] args)
        { 
   
            //两个Task线程和主线程同时执行
            Task task = Task.Factory.StartNew(() =>
            { 
   
                GetDataFromServer(1);
            });
            
            //主线程执行,将信号set为true,调用WaitOne()的线程被释放
            manualResetEvent.Set();
 
            Console.ReadLine();

        }

        static void GetDataFromServer(int serverNumber)
        { 
   
            Console.WriteLine("I get first data from server" + serverNumber);
            manualResetEvent.WaitOne();
            Console.WriteLine("I get second data from server" + serverNumber);
            Thread.Sleep(TimeSpan.FromSeconds(2));
            Console.WriteLine("I get third data from server" + serverNumber);
            manualResetEvent.WaitOne();
            Console.WriteLine("All the data collected from server" + serverNumber);
        }
    }
}

输出:
I get first data from server1
I get second data from server1
I get third data from server1
All the data collected from server1

3.manualResetEvent调用Set()再调用Reset(),task线程在第一个WaitOne()处阻塞。

namespace ManualResetEvent测试
{ 
   
    class Program
    { 
   
        static ManualResetEvent manualResetEvent = new ManualResetEvent(false);

        static void Main(string[] args)
        { 
   
            //两个Task线程和主线程同时执行
            Task task = Task.Factory.StartNew(() =>
            { 
   
                GetDataFromServer(1);
            });
            
            //主线程执行,调用WaitOne()的线程被释放再马上阻塞
            manualResetEvent.Set();
 			manualResetEvent.Reset();
            Console.ReadLine();

        }

        static void GetDataFromServer(int serverNumber)
        { 
   
            Console.WriteLine("I get first data from server" + serverNumber);
            manualResetEvent.WaitOne();
            Console.WriteLine("I get second data from server" + serverNumber);
            Thread.Sleep(TimeSpan.FromSeconds(2));
            Console.WriteLine("I get third data from server" + serverNumber);
            manualResetEvent.WaitOne();
            Console.WriteLine("All the data collected from server" + serverNumber);
        }
    }
}

输出:
I get first data from server1

4.manualResetEvent.Set()事件状态设为true,task线程在第一个WaitOne()处阻塞然后被释放。

namespace ManualResetEvent测试
{ 
   
    class Program
    { 
   
        static ManualResetEvent manualResetEvent = new ManualResetEvent(false);

        static void Main(string[] args)
        { 
   
            //Task线程和主线程同时执行
            Task task = Task.Factory.StartNew(() =>
            { 
   
                GetDataFromServer(1);
            });

			setEvent.Set();
            manualResetEvent.Reset();

            Thread.Sleep(TimeSpan.FromSeconds(8));
            manualResetEvent.Set();

            Console.ReadLine();
        }

        static void GetDataFromServer(int serverNumber)
        { 
   
            Console.WriteLine("I get first data from server" + serverNumber);
            manualResetEvent.WaitOne();
            Console.WriteLine("I get second data from server" + serverNumber);
            Thread.Sleep(TimeSpan.FromSeconds(2));
            Console.WriteLine("I get third data from server" + serverNumber);
            manualResetEvent.WaitOne();
            Console.WriteLine("All the data collected from server" + serverNumber);
        }
    }
}

输出:
先输出 I get first data from server1
然后task被阻塞,8秒后task获得Set()信号,再输出 I get second data from server1
再间隔2秒输出,第二个WaitOne()不会被阻塞
I get third data from server1
All the data collected from server1

5.三个线程异步执行,set()释放所有线程

namespace ManualResetEvent测试
{ 
   
    class Program
    { 
   
        static ManualResetEvent manualResetEvent = new ManualResetEvent(false);

        static void Main(string[] args)
        { 
   
            //两个Task线程和主线程同时执行
            Task task = Task.Factory.StartNew(() =>
            { 
   
                GetDataFromServer(1);
            });

            Task.Factory.StartNew(() =>
            { 
   
                GetDataFromServer(2);
            });

            manualResetEvent.Set();
            manualResetEvent.Reset();

            Thread.Sleep(TimeSpan.FromSeconds(8));
            manualResetEvent.Set();
            
            Console.ReadLine();

        }

        static void GetDataFromServer(int serverNumber)
        { 
   
            Console.WriteLine("I get first data from server" + serverNumber);
            manualResetEvent.WaitOne();
            Console.WriteLine("I get second data from server" + serverNumber);
            Thread.Sleep(TimeSpan.FromSeconds(2));
            Console.WriteLine("I get third data from server" + serverNumber);
            manualResetEvent.WaitOne();
            Console.WriteLine("All the data collected from server" + serverNumber);
        }
    }
}

输出:
先输出
I get first data from server1
I get first data from server2
然后task被阻塞,8秒后task获得Set()信号,再输出
I get second data from server2
I get second data from server1
再间隔2秒输出,第二个WaitOne()不会被阻塞
I get third data from server2
All the data collected from server2
I get third data from server1
All the data collected from server1

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

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

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


相关推荐

  • Python使用免费天气API,获取全球任意地区的天气情况

    Python使用免费天气API,获取全球任意地区的天气情况需求背景:公司是做外贸服装的,在亚马逊平台上有多个地区店铺运营,运营人员需要参考地区的天气情况,上新的服装.所以需要能够获取全球任意地区的天气情况.还需要预测未来10-15天的天气情况.选型API:天气API中有大把免费的api,如:国内的心知天气,国际的雅虎,还有今天的主角:wunderground最终选择了wunderground,原因:1,需求是全球任意地区的(国内API请求国外地区需要收费…

    2022年10月21日
    0
  • ubuntu linux下开启远程唤醒

    ubuntu linux下开启远程唤醒目录启动远程唤醒,需要主板支持才能进行。步骤一:检查计算机硬件是否支持WOL(wakeonlan)功能。步骤二:检查主板和电源是否支持WOL步骤三:检查网卡是否支持WOL步骤四:查看网卡步骤五:查询网卡是否支持远程唤醒步骤六:开启远程唤醒d为关闭g为开启步骤七:参考操作启动远程唤醒,需要主板支持才能进行。步骤一:检查计算机硬件是否支持WOL(wakeonlan)功能。步骤二:检查主板和电源是否支持WOL进入BIOS的PowerManage…

    2022年5月12日
    44
  • PHP JSON_ENCODE 不转义中文汉字的方法

    PHP JSON_ENCODE 不转义中文汉字的方法ios程序中不识别读取到的JSON数据中\u开头的数据。PHP生成JSON的时候,必须将汉字不转义为\u开头的UNICODE数据。网上很多,但是其实都是错误的,正确的方法是在json_encode中加入一个参数JSON_UNESCAPED_UNICODE(bydefault7#zbphp.com)json_encode($data,JSON_UNESCAPED_U

    2022年7月13日
    16
  • ZOJ Problem Set – 2563 Long Dominoes 【如压力dp】

    ZOJ Problem Set – 2563 Long Dominoes 【如压力dp】

    2022年1月13日
    46
  • 测试从零开始-No.6-测试用例设计方法(等价类+边界值)「建议收藏」

    测试从零开始-No.6-测试用例设计方法(等价类+边界值)「建议收藏」问题:有时候用selenium操作浏览器,打开多个页面后,在不用的时候,需要关掉,切换页面需要切换句柄,关掉页面后,也需要重新切换句柄,否则页面接着操作元素会出问题解决方法:

    2022年8月31日
    2
  • 计算机网络放大器的作用,运算放大器

    计算机网络放大器的作用,运算放大器运算放大器(简称“运放”)是具有很高放大倍数的电路单元。在实际电路中,通常结合反馈网络共同组成某种功能模块。它是一种带有特殊耦合电路及反馈的放大器。其输出信号可以是输入信号加、减或微分、积分等数学运算的结果。由于早期应用于模拟计算机中用以实现数学运算,因而得名“运算放大器”。[1]由于早期应用于模拟计算机中,用以实现数学运算,故得名“运算放大器”。运放是一个从功能的角度命名的电路单元,可以由分立的…

    2022年5月22日
    28

发表回复

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

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