Brad Mace
Brad Mace

Reputation: 27886

Determining which Callables are currently running in ExecutorService

I'd like to be able to get the Callables that I've submitted to an ExecutorService (specifically a ThreadPoolExecutor) which are currently in progress (so they're not available via getQueue()).

I tried creating a subclass to override beforeExecute, the but Runnable given there turns out to be a FutureTask, not the original Callable that was submitted.

Is there another way to go about determining the active Callables?


Ultimately there's two things I'd like to do with this information:

  1. Get the running tasks so they can be displayed in the user interface
  2. Check if the file referenced by the Callable matches a pattern, and if so, cancel it

Upvotes: 2

Views: 827

Answers (2)

Brad Mace
Brad Mace

Reputation: 27886

as suggested by axtavt I created a subclass of FutureTask:

public class FutureCallable<V> extends FutureTask<V> {
    private Callable<V> callable;

    public FutureCallable(Callable<V> callable) {
        super(callable);
        this.callable = callable;
    }

    public Callable<V> getCallable() {
        return callable;
    }

}

and overrode a few methods in my ThreadPoolExecutor subclass:

public class CustomThreadPoolExecutor extends ThreadPoolExecutor {
    private Set<FutureCallable<UpdateResult>> running = new HashSet<FutureCallable<UpdateResult>>();

    @Override
    public <T> FutureCallable<T> newTaskFor(Callable<T> callable) {
        return new FutureCallable<T>(callable);
    }

    @Override
    protected void beforeExecute(Thread t, Runnable r) {
        FutureCallable<UpdateResult> task = (FutureCallable<UpdateResult>) r;
        running.add(task);
    }

    @Override
    protected void afterExecute(Runnable r, Throwable t) {
        FutureCallable<UpdateResult> task = (FutureCallable<UpdateResult>) r;
        running.remove(task);
    }

    ...
}

Upvotes: 1

axtavt
axtavt

Reputation: 242706

You can override AbstractExecutorService.newTaskFor(), it should give you access to original Runnables and Callables. Then decorate them with your tracking decorator and pass to super.newTaskFor().

Upvotes: 5

Related Questions