Blog About Contact

How to get the running tasks for a Java Executor...

Published Sat, 7 Jan 2012

I just had the issue of debugging a large concurrent job that ran using Java's Executor and ExecutorService classes for concurrency.

The job comprised of roughly 50,000 tasks submitted recursively over a multi-GB data set that took 5hrs to process. The bug left a single task in the queue hanging indefinitely, thus the job never completing. There's no way to kill a Thread in Java, and if you have blocking I/O it can be difficult to implement interrupt() such that it works correctly.

This is the point I found it's quite difficult to actually expose at run-time what the hell Java's Executor is actually doing at any point in time.

The successful choice I found was to create a custom ThreadPoolExecutor which trapped the creation of a FutureTask and the start/stop of any given task. I expect these hooks are there for this purpose, but it sure isn't obvious how to do this.

It seems odd that the API doesn't include any way to gather info about what's happening inside the Executor, and also, there's not even a toString() implementation for wrapping classes like FutureTask which would bubble your Runnable or Callable classes' toString() methods.

Oh well!

Here's an example:

private static final int NUM_THREADS = 4;
private final Logger log = Logger.getLogger(getClass());

private LinkedBlockingQueue< Runnable> taskQueue = new LinkedBlockingQueue< Runnable>();
private List< Runnable> running = Collections.synchronizedList(new ArrayList());

public void doSomeStuffConcurrently() {
    Executor executor = 
        new ThreadPoolExecutor(NUM_THREADS, NUM_THREADS,
            0L, TimeUnit.MILLISECONDS,

        protected < T> RunnableFuture< T> newTaskFor(final Runnable runnable, T value) {
            return new FutureTask< T>(runnable, value) {
                public String toString() {
                    return runnable.toString();

        protected void beforeExecute(Thread t, Runnable r) {
            super.beforeExecute(t, r);

        protected void afterExecute(Runnable r, Throwable t) {
            super.afterExecute(r, t);
  "RUNNING: " + running);

    executor.execute(new Runnable() {

        public void run() {
            // so some stuff

        public String toString() {
            return "describe the task here!";

About the Author

Richard Nichols is an Australian software engineer with a passion for making things.

Follow him on twitter or subscribe by RSS or email.

You might also enjoy reading -

Discuss / Comment

No one has commented yet.

Add a comment

  • {{e.error}}

Thanks for your comment!/

Valid email address required.
Posting message, please wait...