zoukankan      html  css  js  c++  java
  • AutoResetEvent实现单并发控制

    AutoResetEvent是EventWaitHandle的一个简单包装,内部没有额外的任何逻辑。它最大的特点就是,调用了Set方法将事件设为true之后,其中一个等待线程得到执行后,它会自动调用Reset方法,将事件信号设为false,以阻塞其它的线程。相当于放一个线程进来,门自动就关了(自动门)

    例子,使用AutoResetEvent实现一个简单的线程同步锁。

     1  private class SimpleWaitLock : IDisposable
     2         {
     3             //初始化一定要是true,否则,第一个调用Enter方法的线程会被阻塞
     4             private AutoResetEvent m_autoResetEvent = new AutoResetEvent(true);
     5             
     6             
     7             public void Enter()
     8             {
     9                 //第一个线程调用这个方法后,事件将会为false,其他线程会被阻塞
    10                 m_autoResetEvent.WaitOne();                
    11                 Console.WriteLine("Thread {0} Enter;",Thread.CurrentThread.Name);
    12                 Thread.Sleep(100);
    13                 Exit();
    14             }
    15             public void Exit()
    16             {
    17                 Console.WriteLine("Thread {0} Exit;", Thread.CurrentThread.Name);
    18                 m_autoResetEvent.Set();
    19                 
    20             }
    21             public void Dispose()
    22             {
    23                 m_autoResetEvent.Dispose();
    24                 Console.WriteLine("Thread {0} dispose;", Thread.CurrentThread.Name);
    25             }
    26         }
    27         static void Main()
    28         {
    29             SimpleWaitLock slock = new SimpleWaitLock();
    30             for (int i = 0; i < 10; i++)
    31             {
    32                 Thread thread = new Thread(slock.Enter);
    33                 thread.Name = "thread" + i.ToString();
    34                 thread.Start();                
    35             }
    36             Console.Read();
    37         }
    38      
    39 
    40     }

    执行结果:

    ManualResetEvent

    ManualResetEvent是EventWaitHandle的一个简单包装,内部也没有额外的任何逻辑。它和AutoResetEvent唯一的不同是,调用了Set方法将事件设为true后,不会去调用Reset方法,这将导致事件一直处于true,其它等待的多个线程都会得到执行,直到你手动调用Reset方法。相当于你把门打开后,需要手动去关(非自动门)

    View Code
     1  private class SimpleWaitLock : IDisposable
     2         {
     3             //初始化一定要是true,否则,第一个调用Enter方法的线程会被阻塞
     4             private ManualResetEvent m_mannualResetEvent = new ManualResetEvent(false);
     5             
     6             
     7             public void Enter()
     8             {
     9                 //第一个线程调用这个方法后,事件将会为false,其他线程会被阻塞                
    10                 m_mannualResetEvent.WaitOne();                
    11                 Console.WriteLine("Thread {0} Enter;",Thread.CurrentThread.Name);
    12                 Thread.Sleep(100);
    13                 
    14             }
    15             public void Exit()
    16             {
    17                 //Console.WriteLine("Thread {0} Exit;", Thread.CurrentThread.Name);
    18                 m_mannualResetEvent.Set();          
    19                 
    20             }
    21             public void Dispose()
    22             {
    23                 m_mannualResetEvent.Dispose();
    24                 Console.WriteLine("Thread {0} dispose;", Thread.CurrentThread.Name);
    25             }
    26         }
    27         static void Main()
    28         {
    29             SimpleWaitLock slock = new SimpleWaitLock();
    30             for (int i = 0; i < 10; i++)
    31             {
    32                 Thread thread = new Thread(slock.Enter);
    33                 thread.Name = "thread" + i.ToString();
    34                 thread.Start();                
    35             }
    36             Thread.Sleep(1000);
    37             Console.WriteLine("The door is open, all threads can go over...");
    38             slock.Exit();
    39             Console.Read();
    40         }
    41      
    42 
    43     }

    执行结果如下:

    总结:

    1、看起来,ManualResetEvent更加自由、开放。如果把AutoResetEvent看作是只能单人通过的独木桥的话,那么ManualResetEvent就像一座城门,一下子可以涌入千军万马,当然你也可以随时关闭城门,让后面的人进不来。

    2、AutoResetEvent.Set() = ManualResetEvent.Set() + ManualResetEvent.Reset();

    3、如果共享资源仅允许一个线程单独使用的情况下,可以选择AutoResetEvent;如果共享资源允许多个线程同时使用,则可以选择ManualResetEvent

    4、如果要控制多个线程暂停、继续,可以选择ManualResetEvent

    5。而Semaphore可实现多并发同步控制

  • 相关阅读:
    python基础总结二
    HTTP和HTTPS的区别
    通过HTTP请求响应过程了解HTTP协议
    稳定性测试+易用性测试
    容错测试点
    功能测试思考点
    功能测试-UI测试思考点
    字符编码-11
    字典+再识函数-8
    web API的概念
  • 原文地址:https://www.cnblogs.com/Finding2013/p/3012616.html
Copyright © 2011-2022 走看看