zoukankan      html  css  js  c++  java
  • 线程学习笔记 等待句柄和线程池(摘自https://blog.gkarch.com/threading/part2.html#manualresetevent)

    //如果你的应用有很多线程,这些线程大部分时间都在阻塞,那么可以通过调用ThreadPool.RegisterWaitForSingleObject来减少资源消耗。这个方法接受一个委托,它会在向等待句柄发信号时执行。当处于等待状态时,它不会浪费线程资源:
    static ManualResetEvent _starter = new ManualResetEvent (false);
    
    public static void Main()
    {
      RegisteredWaitHandle reg = ThreadPool.RegisterWaitForSingleObject
                                 (_starter, Go, "Some Data", -1, true);
      Thread.Sleep (5000);
      Console.WriteLine ("Signaling worker...");
      _starter.Set();
      Console.ReadLine();
      reg.Unregister (_starter);    // 完成后的清理
    }
    
    public static void Go (object data, bool timedOut)
    {
      Console.WriteLine ("Started - " + data);
      // 执行任务 ....
    }
    输出结果:
    (5 second delay)
    Signaling worker...
    Started - Some Data
    //当向等待句柄发信号时(或者已超时),委托会在一个线程池线程运行。
    //除等待句柄和委托外,RegisterWaitForSingleObject还接受一个“黑盒”对象,它会被传递给委托的目标方法(像ParameterizedThreadStart一样);还有一个以毫秒为单位的超时时间(-1 代表没有超时时间);和一个布尔值用来设置请求是一次性的还是可重复的。
    RegisterWaitForSingleObject在需要处理很多并发请求的应用服务器中非常有用。假如你需要在ManualResetEvent上阻塞,调用WaitOne就可以了:
    void AppServerMethod()
    {
      _wh.WaitOne();
      // ... 继续执行
    }
    //如果 100 个客户端调用这个方法,就会有 100 个服务端线程被浪费在阻塞上。把_wh.WaitOne换成RegisterWaitForSingleObject可以让方法立即返回,就不会浪费线程资源:
    void AppServerMethod
    {
      RegisteredWaitHandle reg = ThreadPool.RegisterWaitForSingleObject
       (_wh, Resume, null, -1, true);
      // ...
    }
    
    static void Resume (object data, bool timedOut)
    {
      // ... 继续执行
    }
  • 相关阅读:
    收集最好的Mac软件和使用方法
    为什么使用Binder而不是其他IPC机制
    Android什么时候进行View中Background的加载
    Android属性动画源代码解析(超详细)
    JMockit工具总结
    路由器和交换机的区别
    6种 @Transactional 注解失效场景
    20个使用 Java CompletableFuture的例子
    书写高质量SQL的30条建议
    Netty之什么是 TCP 拆、粘包?如何解决?
  • 原文地址:https://www.cnblogs.com/kexb/p/6105530.html
Copyright © 2011-2022 走看看