Количество активных задач, использующих ThreadPoolExecutor - PullRequest
6 голосов
/ 07 апреля 2011

Я использую ThreadPoolExecutor для выполнения задач в моем Java-приложении.У меня есть требование, где я хочу получить количество активных задач в очереди в любой момент времени в очереди исполнителя.Я посмотрел на javadoc для ThreadPoolExecutor и нашел два соответствующих метода: getTaskCount() и getCompletedTaskCount().

В соответствии с документацией я мог получить количество запланированных задач и выполненных задач извышеупомянутые два метода соответственно.Но я не могу найти решение для получения количества активных задач в очереди в любой момент времени.Я могу сделать что-то вроде:

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

Но количество неудачных задач не доступно напрямую, чтобы прийти к намеченному расчету.

Я что-то здесь упускаю?

Ответы [ 2 ]

20 голосов
/ 07 апреля 2011

Я не думаю, что вам нужно знать число неудачных вычислений с помощью расчета, который вы пытаетесь использовать.

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

Было бы (приблизительно) достаточно.

<Ч />

В качестве альтернативы вы можете использовать getQueue() с size():

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

Этот ответ предполагает, что вы ищете счетчик "еще не завершен". Ваш вопрос противоречит сам себе, поэтому я не совсем уверен, что вы спрашиваете. Ответьте на мой комментарий по вашему вопросу, если это не так, и я соответствующим образом обновлю этот ответ.

4 голосов
/ 07 апреля 2011

Вы пытались использовать методы 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++;
                }
            }
       }

}
...