Number of active tasks using ThreadPoolExecutor

落花浮王杯 提交于 2019-12-30 06:45:55

问题


I am using a ThreadPoolExecutor to execute tasks in my Java application. I have a requirement where I want to get the number of active tasks in the queue at any point in time in the executor queue . I looked up at the javadoc for ThreadPoolExecutor and found two relevant methods: getTaskCount() and getCompletedTaskCount().

Per the documentation, I could get the number of scheduled tasks and completed tasks from the above two methods respectively. But I am not able to find a solution for getting the number of active tasks in the queue at any point in time. I can do something like:

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

But the number of failed tasks is not directly available to arrive at the intended calculation.

Am I missing something here ?


回答1:


I don't think you need to know the failed count with the calculation you're trying to use.

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

Would be (approximately) sufficient.


Alternatively, you can use getQueue() with size():

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

This answer presumes you're looking for a "not yet completed" count. Your question contradicts itself so I'm not completely certain what you're asking. Reply to my comment on your question if this is incorrect, and I'll update this answer accordingly.




回答2:


Have you tried using the beforeExecute and afterExecute methods? These are called before and after a task is executed. The after execute method even supplies a throwable as a second argument, so you know when a task has failed.

You could add a hook so that beforeExecute increments the value of the active tasks, and afterExecute decrements it. Ofcourse, these methods are called on their respective fields, so that you would have to synchronize the result on a mutual lock Object.

To use these methods, just override the ThreadPoolExecutor object of your choice and add the hook there.

For instance, the following code should hopefully work:

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++;
                }
            }
       }

}


来源:https://stackoverflow.com/questions/5572865/number-of-active-tasks-using-threadpoolexecutor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!