使用ThreadPoolExecutor的活动任务数

我正在使用ThreadPoolExecutor在我的Java应用程序中执行任务。 我有一个要求,我想在执行程序队列中的任何时间点获取队列中的活动任务数。 我查看了ThreadPoolExecutor的javadoc ,发现了两个相关的方法: getTaskCount()getTaskCount() getCompletedTaskCount()

根据文档,我可以分别从上述两种方法中获得计划任务和已完成任务的数量。 但我无法找到在任何时间点获取队列中活动任务数的解决方案。 我可以这样做:

 getTaskCount() = getCompletedTaskCount() + failed tasks + active tasks 

但是,无法直接获得失败任务的数量以达到预期的计算。

我在这里错过了什么吗?

我认为您不需要通过您尝试使用的计算来了解失败的计数。

 long submitted = executor.getTaskCount(); long completed = executor.getCompletedTaskCount(); long notCompleted = submitted - completed; // approximate 

会(大约)足够。


或者,您可以使用带有size() getQueue() size()

 int queued = executor.getQueue().size(); int active = executor.getActiveCount(); int notCompleted = queued + active; // approximate 

这个答案假设您正在寻找“尚未完成”的计数。 你的问题与自己相矛盾,所以我不完全确定你在问什么。 如果这不正确,请回复我对您的问题的评论,我会相应地更新此答案。

您是否尝试过使用beforeExecute和afterExecute方法? 在执行任务之前和之后调用它们。 after execute方法甚至提供throwable作为第二个参数,因此您知道任务何时失败。

您可以添加一个钩子,以便beforeExecute增加活动任务的值,afterExecute减少它。 当然,这些方法在各自的字段上调用,因此您必须在相互锁定对象上同步结果。

要使用这些方法,只需覆盖您选择的ThreadPoolExecutor对象并在其中添加钩子。

例如,以下代码应该有效:

 public class MyExecutor extends ThreadPoolExecutor { //Lock object used for synchronization private final Object lockObject = new Object(); //Contains the active task count private int activeTaskCount = 0; //Failed task count private int failedTaskCount = 0; private int succeededTaskCount = 0; public MyExecutor () { //call super here with your parameters; } public int getActiveTaskCount(){ synchronized(lockObject){ return activeTaskCount; } } public int getFailedTaskCount(){ synchronized(lockObject){ return failedTaskCount ; } } public int getSucceededTaskCount(){ synchronized(lockObject){ return succeededTaskCount ; } } protected void beforeExecute(Thread t, Runnable r){ super.beforeExecute(t,r); synchronized(lockObject){ activeTaskCount++; } } protected void afterExecute(Runnable r,Throwable t){ super.afterExecute(r,t); synchronized(lockObject){ activeTaskCount--; if(t!=null){ failedTaskCount++; }else{ succeededTaskCount++; } } } }