• 多线程编程中的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;
                }
            }
        }
    }
  • 相关阅读:
    Eclipse查看git中的历史,显示详细时间
    eclipse git pull 代码 failed 并且报DIRTY_WORKTREE.classpath
    ResultMap(还没细看)
    mybatis中<include>标签的作用
    mybatis之<trim prefix="" suffix="" suffixOverrides="" prefixOverrides=""></trim>
    hdu 1285 确定比赛名次(拓扑排序)
    hdu 1257 最少拦截系统
    java 高精度模板
    最小生成树 hdu 1233 模板题
    manacher算法 O(n) 求字符串中最长回文子串 hdu 3068(模板题)
  • 原文地址:https://www.cnblogs.com/-s11900085/p/8986627.html
Copyright © 2020-2023  润新知