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 note 30 断点续传
    python note 29 线程创建
    python note 28 socketserver
    python note 27 粘包
    python note 26 socket
    python note 25 约束
    Sed 用法
    python note 24 反射
    python note 23 组合
    python note 22 面向对象成员
  • 原文地址:https://www.cnblogs.com/Finding2013/p/3012616.html
Copyright © 2011-2022 走看看