zoukankan      html  css  js  c++  java
  • 多线程编程中的EventWaitHandler

    如果事件初始为终止状态,首次waitone()时候不进行线程阻塞,为非终止状态时候,首次waitone()时候进行线程阻塞。当然,该状态也要结合一下的EventResetMode的值进行结合使用。

     EventResetMode.AutoReset 自动重置,也就是自动重置事件状态,自动的话,他会在首次waitone之后立即改变事件为非终止状态。就像这样{如果手动重置事件的初始化为终止状态,则首次waitone()不进行线程阻塞,但是会立即改变事件状态的状态为非终止状态,当以后waitone()的时候,都会阻塞线程}

    EventResetMode.ManualReset 手动重置,它对于线程的阻塞决定于上一个参数是否为终止状态,也就是说,如果初始值设置为终止状态,则它的线程如果不手动进行手动设置,则一直不进行线程阻塞,如果初始值是非终止状态,则每个waione()都会阻塞,除非手动使用set()之类的方法设置为终止状态为止。

    using System;
    using System.Threading;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace EventWaitHandleDemo
    {
        class Program
        {
            static EventWaitHandle eHandle;
    
            static void UnblockDemo()
            {
                Console.WriteLine("测试EventWaitHandle的初始终止状态");
                eHandle = new EventWaitHandle(true, EventResetMode.AutoReset);//eHandle初始为终止状态,模式为AutoReset
                eHandle.WaitOne();//由于EventWaitHandle对象eHandle初始状态为终止状态,所以这里第一次调用WaitOne时阻塞被立即释放,又由于eHandle为AutoReset模式,所以之后eHandle会被置为非终止状态
                Console.WriteLine("线程未被阻塞");
                eHandle.WaitOne();//由于此时eHandle已经为非终止状态,所以此时调用WaitOne线程会被阻塞
                Console.WriteLine("线程被阻塞");
            }
    
            static void BlockDemo()
            {
                Console.WriteLine("测试EventWaitHandle的初始非终止状态");
                eHandle = new EventWaitHandle(false, EventResetMode.AutoReset);//eHandle初始为非终止状态,模式为AutoReset
                eHandle.WaitOne();//由于EventWaitHandle对象eHandle初始状态为非终止状态,所以这里第一次调用WaitOne时,线程就被组塞了
                Console.WriteLine("线程被阻塞");
            }
    
            static void AutoResetDemo()
            {
                Console.WriteLine("测试EventWaitHandle的AutoReset模式");
                eHandle = new EventWaitHandle(false, EventResetMode.AutoReset);//eHandle初始为非终止状态,模式为AutoReset
                ThreadPool.QueueUserWorkItem(new WaitCallback((object o) =>
                {
                    //启动另一个线程,每隔3秒钟调用一次eHandle.Set方法,为主线程释放一次阻塞,一共释放3次
                    for (int i = 0; i < 3; i++)
                    {
                        Thread.Sleep(3000);
                        eHandle.Set();//由于eHandle处于AutoReset模式,所以每次使用Set将eHandle置为终止状态后,待被WaitOne阻塞的线程被释放后,eHandle又会被自动置回非终止状态
                    }
                }), null);
    
                eHandle.WaitOne();//线程第一次被WaitOne阻塞
                Console.WriteLine("第一次WaitOne调用阻塞已被释放,3秒后第二次WaitOne调用的阻塞会被释放");
                eHandle.WaitOne();//线程第二次被WaitOne阻塞
                Console.WriteLine("第二次WaitOne调用阻塞已被释放,3秒后第三次WaitOne调用的阻塞会被释放");
                eHandle.WaitOne();//线程第三次被WaitOne阻塞
                Console.WriteLine("第三次WaitOne调用阻塞已被释放,所有WaitOne调用的阻塞都已被释放");
            }
    
            static void ManualResetDemo()
            {
                Console.WriteLine("测试EventWaitHandle的ManualReset模式");
                eHandle = new EventWaitHandle(false, EventResetMode.ManualReset);//eHandle初始为非终止状态,模式为ManualReset
                ThreadPool.QueueUserWorkItem(new WaitCallback((object o) =>
                {
                    //启动另一线程,3秒后调用一次eHandle.Set方法,为主线程释放WaitOne阻塞
                    Thread.Sleep(3000);
                    eHandle.Set();//由于eHandle处于ManualReset模式,所以一旦使用Set将eHandle置为终止状态后,在eHandle的Reset被调用前eHandle会一直处于终止状态,在eHandle调用Reset前,所有被WaitOne阻塞的线程会立即得到释放
                }), null);
    
                eHandle.WaitOne();//线程第一次被WaitOne阻塞
                Console.WriteLine("第一次WaitOne调用阻塞已被释放,第二次WaitOne调用的阻塞会被立即释放");
                eHandle.WaitOne();//线程第二次被WaitOne阻塞
                Console.WriteLine("第二次WaitOne调用阻塞已被释放,第三次WaitOne调用的阻塞会被立即释放");
                eHandle.WaitOne();//线程第三次被WaitOne阻塞
                Console.WriteLine("第三次WaitOne调用阻塞已被释放,所有WaitOne调用的阻塞都已被释放");
    
                eHandle.Reset();//调用eHandle的Reset方法,将eHandle手动置回非终止状态,之后再调用WaitOne方法就会被阻塞了
                eHandle.WaitOne();//线程第四次被WaitOne阻塞
                Console.WriteLine("第四次WaitOne调用阻塞已被释放");
            }
    
            static void Main(string[] args)
            {
                Console.Write("你想测试哪一个方法1=UnblockDemo,2=BlockDemo,3=AutoResetDemo,4=ManualResetDemo:");
                switch (Console.ReadLine())
                {
                    case "1":
                        UnblockDemo();
                        break;
                    case "2":
                        BlockDemo();
                        break;
                    case "3":
                        AutoResetDemo();
                        break;
                    case "4":
                        ManualResetDemo();
                        break;
                    default:
                        break;
                }
            }
        }
    }
  • 相关阅读:
    739. Daily Temperatures
    556. Next Greater Element III
    1078. Occurrences After Bigram
    1053. Previous Permutation With One Swap
    565. Array Nesting
    1052. Grumpy Bookstore Owner
    1051. Height Checker
    数据库入门及SQL基本语法
    ISCSI的概念
    配置一个IP SAN 存储服务器
  • 原文地址:https://www.cnblogs.com/-s11900085/p/8986627.html
Copyright © 2011-2022 走看看