【问题标题】:Active threads in ExecutorServiceExecutorService 中的活动线程
【发布时间】:2010-09-09 23:53:42
【问题描述】:

任何想法如何确定当前在ExecutorService 中运行的活动线程数?

【问题讨论】:

    标签: java multithreading concurrency


    【解决方案1】:

    使用ThreadPoolExecutor 实现并在其上调用getActiveCount()

    int getActiveCount() 
    // Returns the approximate number of threads that are actively executing tasks.
    

    ExecutorService 接口没有为此提供方法,它取决于实现。

    【讨论】:

      【解决方案2】:

      假设pool是ExecutorService实例的名字:

      if (pool instanceof ThreadPoolExecutor) {
          System.out.println(
              "Pool size is now " +
              ((ThreadPoolExecutor) pool).getActiveCount()
          );
      }
      

      【讨论】:

        【解决方案3】:

        查看Executors.newFixedThreadPool()的源代码:

        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
        

        ThreadPoolExecutor 有一个 getActiveCount() 方法。因此,您可以将 ExecutorService 转换为 ThreadPoolExecutor,或者直接使用上面的代码来获取一个。然后你可以调用getActiveCount()

        【讨论】:

          【解决方案4】:

          ExecutorService 接口没有定义检查池中工作线程数量的方法,因为这是一个实现细节

          public int getPoolSize()
          Returns the current number of threads in the pool.
          

          在 ThreadPoolExecutor 类上可用

          导入 java.util.concurrent.LinkedBlockingQueue; 导入 java.util.concurrent.ThreadPoolExecutor; 导入 java.util.concurrent.TimeUnit; 公共类池大小 { 公共静态无效主要(字符串[]参数){ ThreadPoolExecutor 执行器 = new ThreadPoolExecutor(10, 20, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue()); System.out.println(executor.getPoolSize()); } }

          但这需要您显式创建 ThreadPoolExecutor,而不是使用返回 ExecutorService 对象的 Executors 工厂。您始终可以创建自己的工厂来返回 ThreadPoolExecutors,但仍然会留下使用具体类型而不是其接口的糟糕形式。

          一种可能性是提供您自己的 ThreadFactory,它在已知线程组中创建线程,然后您可以对其进行计数

          导入 java.util.concurrent.ExecutorService; 导入 java.util.concurrent.Executors; 导入 java.util.concurrent.ThreadFactory; 公共类 PoolSize2 { 公共静态无效主要(字符串[]参数){ final ThreadGroup threadGroup = new ThreadGroup("workers"); ExecutorService executor = Executors.newCachedThreadPool(new ThreadFactory() { 公共线程 newThread(Runnable r) { 返回新线程(线程组,r); } }); System.out.println(threadGroup.activeCount()); } }

          【讨论】:

          • 当且仅当运行环境允许实现为线程设置组时才可以(例如 Google App Engine)
          【解决方案5】:

          我有同样的问题,所以创建了一个简单的 Runnable 来跟踪 ExecutorService 实例。

          import java.util.concurrent.ExecutorService;
          import java.util.concurrent.ThreadPoolExecutor;
          
          public class ExecutorServiceAnalyzer implements Runnable
          {
              private final ThreadPoolExecutor threadPoolExecutor;
              private final int timeDiff;
          
              public ExecutorServiceAnalyzer(ExecutorService executorService, int timeDiff)
              {
                  this.timeDiff = timeDiff;
                  if (executorService instanceof ThreadPoolExecutor)
                  {
                      threadPoolExecutor = (ThreadPoolExecutor) executorService;
                  }
                  else
                  {
                      threadPoolExecutor = null;
                      System.out.println("This executor doesn't support ThreadPoolExecutor ");
                  }
          
              }
          
              @Override
              public void run()
              {
                  if (threadPoolExecutor != null)
                  {
                      do
                      {
                          System.out.println("#### Thread Report:: Active:" + threadPoolExecutor.getActiveCount() + " Pool: "
                                  + threadPoolExecutor.getPoolSize() + " MaxPool: " + threadPoolExecutor.getMaximumPoolSize()
                                  + " ####");
                          try
                          {
                              Thread.sleep(timeDiff);
                          }
                          catch (Exception e)
                          {
                          }
                      } while (threadPoolExecutor.getActiveCount() > 1);
                      System.out.println("##### Terminating as only 1 thread is active ######");
                  }
          
              }
          }
          

          您可以简单地将它与您的执行程序一起使用来获取 ThreadPool 的状态

          ExecutorService executorService = Executors.newFixedThreadPool(4);
              executorService.execute(new ExecutorServiceAnalyzer(executorService, 1000));
          

          【讨论】:

            【解决方案6】:

            在线程上放置一个静态 volatile 计数器,该计数器在线程被激活和停用时更新。 另请参阅 API。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-01-02
              • 1970-01-01
              • 2019-03-15
              • 2014-08-01
              • 1970-01-01
              • 2011-07-11
              相关资源
              最近更新 更多