zoukankan      html  css  js  c++  java
  • AutoResetEvent实现并发同步

    AutoResetEvent,继承自EventWaitHandle,用在多线程中保护对共享资源的访问,保证每次只能有一个线程对共享资源进行访问

    AutoResetEvent最特别之处,在于每次保证只有一个线程执行逻辑,其他的线程只能等待。

    AutoResetEvent通过信号量来阻塞和释放线程。其基本原理如下:

    1、如果AutoResetEvent在无信号状态时,执行了WaitOne()方法之后,当前线程就会被阻塞,直到该AutoResetEvent在其他地方执行了Set()方法后,此时AutoResetEvent就获得了信号并释放一个线程,然后自动执行Reset()方法(即失去信号)。

    如果当AutoResetEvent执行Set()方法后,没有等待任何等待的线程,则该AutoResetEvent会一直保持持有信号;

    2、如果AutoResetEvent在有信号时,执行了WaitOne方法,当前线程会被立即释放,并且AutoResetEvent也会失去信号。

    代码如下所示:

            
    static AutoResetEvent autoResetEvent=new AutoResetEvent(true);
    static void WorkOnAutoResetEvent(string threadName) { Console.WriteLine($"{threadName} 正在等待中..."); autoResetEvent.WaitOne(); Console.WriteLine($"{threadName} 执行中..."); Thread.Sleep(1000); Console.WriteLine($"{threadName} 执行完毕!"); //得到信号,并释放一个被阻塞的线程,然后丢失信号(即自动执行Reset()方法);如果没有线程可以被释放,则它会一直保持信号 autoResetEvent.Set(); }

    Main中代码如下所示:

                for (int i = 0; i < 3; i++) {
                    string threadName = $"thread_{i}";
                    var thread = new Thread(delegate ()
                      {
                          WorkOnAutoResetEvent(threadName);
                      });
                    thread.Start();
                }

    结果:

      

    为何AutoResetEvent会被以Auto开始的单词命名,因为它在得到信号并释放一个被阻塞的线程之后,会自动的执行Reset()方法,即自动丢失信号,这就是它的自动之处。

    当然,如果它在得到信号,但此时并没有任何阻塞的线程被释放,它就会一直保持持有信号,直到下一个WaitOne()方法被执行。

    在调用Set()方法之后,它就获得了信号,如果释放了一个阻塞的线程,它会自动执行Reset()丢失信号;如果没有释放线程,则它不会丢失信号。这是关键之处!

    参考文献:https://docs.microsoft.com/en-us/dotnet/api/system.threading.autoresetevent?view=netcore-3.1#explicit-interface-implementations

  • 相关阅读:
    js阶段循环(for,while,do-while,for-in),判断(if,switch),练习题
    翻牌器
    用 VSCode 调试网页的 JS 代码
    图形化设置数据库规则
    js中ES6数据结构Map 、Set 、WeakMap 、 WeakSet
    css的filter方法,给图片添加滤镜
    使用<a-select>时,placeholder不起作用,提示语不显示
    Vue数据更新但页面没有更新的多种情况
    react事件处理-函数绑定
    在css中使用js定义的变量
  • 原文地址:https://www.cnblogs.com/williamwsj/p/13853395.html
Copyright © 2011-2022 走看看