【发布时间】:2016-01-25 10:19:05
【问题描述】:
我有一个服务器,它有多个使用 java executorService 实现的工作线程(即线程池)
我的问题是,如果线程池中没有可用的空闲线程,我无法每秒记录等待处理的作业长度。
注意:日志记录不是我的问题,但我希望能够查看有多少任务/作业正在等待工作线程处理,是否可以查看等待队列的长度(不是线程池)内部执行者服务?
我不知道如何实现这个东西。
【问题讨论】:
标签: java multithreading
我有一个服务器,它有多个使用 java executorService 实现的工作线程(即线程池)
我的问题是,如果线程池中没有可用的空闲线程,我无法每秒记录等待处理的作业长度。
注意:日志记录不是我的问题,但我希望能够查看有多少任务/作业正在等待工作线程处理,是否可以查看等待队列的长度(不是线程池)内部执行者服务?
我不知道如何实现这个东西。
【问题讨论】:
标签: java multithreading
ThreadPoolExecutor 构造函数接受 BlockingQueue 参数,该参数是用于存储等待作业的 Queue 实现。您可以使用getQueue() 方法请求此队列,然后检查队列的大小:
System.out.println("Number of waiting jobs: "+executor.getQueue().size());
注意这个方法在ExecutorService接口中是不可用的,因此最好显式构造ThreadPoolExecutor而不是使用Executors.newFixedThreadPool和朋友:
ThreadPoolExecutor executor = new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
虽然 OpenJDK/OracleJDK 中的 Executors.newFixedThreadPool 具有相同的作用,但未指定,因此使用 (ThreadPoolExecutor)Executors.newFixedThreadPool(nThreads) 可能会在未来的 Java 版本或替代 JDK 实现中导致 ClassCastException。
【讨论】:
ThreadPoolExecutor 的其他方法,例如getTaskCount()、getActiveCount() 等。可能他们会回答您的问题。
如果您可以假设您的服务器使用的ExecutorService 实现是ThreadPoolExecutor,那么您可以使用方法getQueue() 返回尚未分配给Worker 的任务数。
/**
* Returns the task queue used by this executor. Access to the
* task queue is intended primarily for debugging and monitoring.
* This queue may be in active use. Retrieving the task queue
* does not prevent queued tasks from executing.
*
* @return the task queue
*/
public BlockingQueue<Runnable> getQueue() {
return workQueue;
}
所以你可以这样运行:
if(LOGGER.isDebugEnabled()) {
LOGGER.debug(String.format("Pending tasks: %d", executor.getQueue().size()));
}
【讨论】:
建议使用 ThreadPoolExecutor 而不是 ExecutorService。 您可以利用 ThreadPoolExecutor 类中存在的阻塞队列。这将为您提供等待的线程数。
ThreadPoolExecutor 类也有方法来获取提交任务和执行任务的计数。
参考
希望对你有帮助
【讨论】: