Java Specialists' Java Training Europehome of the java specialists' newsletter

The Java Specialists' Newsletter
Issue 2282015-04-30 Category: Tips and Tricks Java version: Java 5,6,7,8,...

GitHub Subscribe Free RSS Feed

Extracting Real Task from FutureTask

by Dr. Heinz M. Kabutz
ExecutorService allows us to submit either Callable or Runnable. Internally, this is converted to a FutureTask, without the possibility of extracting the original task. In this newsletter we look at how we can dig out the information using reflection.

Welcome to the 228th edition of The Java(tm) Specialists' Newsletter. As you probably know, I live on an island in the Mediterranean Sea. And no, I don't own the entire island, just a large enough chunk so that my neighbours generally don't complain about our noise. This is a good thing, as my son started an alternative punk rock band three years ago with his friends. We have been collecting egg boxes from the whole village of Chorafakia to try contain the drumming. In January our little band came first in Greece at the Global Battle of the Bands competition and this past Sunday they competed in the world final in Oslo. Unfortunately I could not attend, but despite their #1 fan not being there, they managed to place 4th in the world. Here is Pull the Curtain, which I watched them produce in Athens. Well done my boy!

NEW: Please see our new "Extreme Java" course, combining concurrency, a little bit of performance and Java 8. Extreme Java - Concurrency & Performance for Java 8.

Extracting Real Task from FutureTask

One of the annoyances of the ThreadPoolExecutor and its subclass ScheduledThreadPoolExecutor, is that the tasks that we submit are wrapped with a FutureTask without a possibility of us getting the original task again. I wrote about this in newsletter 154, where I tackled the challenge of resubmitting failed timed tasks.

However, in this newsletter, I would like to show a small class that can extract the Runnable or Callable from the FutureTask that is returned from the ThreadPoolExecutor. Before we get into the details, here are the various ways I can think of where you might see a FutureTask wrapper:

  1. When you call shutdownNow(), a Collection of Runnables is returned. These are not the Runnables that we submitted, but the FutureTask wrapper objects.
  2. If you specify a RejectedExecutionHandler, the Runnable that is passed into the rejectedExecution() method is again the FutureTask wrapper.
  3. The beforeExecute() and afterExecute() methods that you can override again provide you with the wrapper object.

The FutureTask always contains a Callable. If we submit a Runnable to the ThreadPoolExecutor, it wraps this with a Callable adapter using the Executors.callable(Runnable) method. I make certain assumptions in my JobDiscoverer that could certainly not be true on other implementations of the FutureTask. I assume that it contains a field called "callable". Furthermore I assume that if the type is the same as what we would get from calling Executors.callable(), that initially a Runnable has been passed into the ThreadPoolExecutor. I can think of quite a few scenarios in which this assumption is false.

Here is my JobDiscoverer class, which uses reflection to find out what the type is. Since the result can be either a Runnable or a Callable, I need to return Object. The code is relatively straightforward:

import java.lang.reflect.*;
import java.util.concurrent.*;

public class JobDiscoverer {
  private final static Field callableInFutureTask;
  private static final Class<? extends Callable> adapterClass;
  private static final Field runnableInAdapter;

  static {
    try {
      callableInFutureTask =
      adapterClass = Executors.callable(new Runnable() {
        public void run() { }
      runnableInAdapter =
    } catch (NoSuchFieldException e) {
      throw new ExceptionInInitializerError(e);

  public static Object findRealTask(Runnable task) {
    if (task instanceof FutureTask) {
      try {
        Object callable = callableInFutureTask.get(task);
        if (adapterClass.isInstance(callable)) {
          return runnableInAdapter.get(callable);
        } else {
          return callable;
      } catch (IllegalAccessException e) {
        throw new IllegalStateException(e);
    throw new ClassCastException("Not a FutureTask");

In my sample code, I submit ten jobs to an ExecutorService, both Runnable and Callable interleaved. Each of the tasks would block indefinitely. They also have overridden the toString() method to return the type of class they are. I then call shutdownNow() and first print out the values in the result list, followed by what our JobDiscoverer returns. Again, the code is fairly simple. The one thing that might be puzzling is that some of the threads show that they were interrupted, and others don't. I will leave that as an exercise to the reader to figure out :-) [It's also not difficult.]

import java.util.*;
import java.util.concurrent.*;

public class JobDiscovererTest {
  public static void main(String... args) {
    final CountDownLatch latch = new CountDownLatch(1);
    ExecutorService pool = Executors.newFixedThreadPool(3);
    for (int i = 0; i < 5; i++) {
      final int finalI = i;
      pool.submit(new Runnable() {
        public void run() {
          try {
          } catch (InterruptedException consumeAndExit) {
            System.out.println(Thread.currentThread().getName() +
                " was interrupted - exiting");

        public String toString() {
          return "Runnable: " + finalI;
      pool.submit(new Callable<String>() {
        public String call() throws InterruptedException {
          return "success";

        public String toString() {
          return "Callable: " + finalI;

    // Note: the Runnables returned from shutdownNow are NOT
    // the same objects as we submitted to the pool!!!
    List<Runnable> tasks = pool.shutdownNow();

    System.out.println("Tasks from ThreadPool");
    for (Runnable task : tasks) {
      System.out.println("Task from ThreadPool " + task);

    System.out.println("Using our JobDiscoverer");

    for (Runnable task : tasks) {
      Object realTask = JobDiscoverer.findRealTask(task);
      System.out.println("Real task was actually " + realTask);

The output on my machine is the following:

Tasks from ThreadPool
pool-1-thread-1 was interrupted - exiting
pool-1-thread-3 was interrupted - exiting
Task from ThreadPool java.util.concurrent.FutureTask@5a07e868
Task from ThreadPool java.util.concurrent.FutureTask@76ed5528
Task from ThreadPool java.util.concurrent.FutureTask@2c7b84de
Task from ThreadPool java.util.concurrent.FutureTask@3fee733d
Task from ThreadPool java.util.concurrent.FutureTask@5acf9800
Task from ThreadPool java.util.concurrent.FutureTask@4617c264
Task from ThreadPool java.util.concurrent.FutureTask@36baf30c

Using our JobDiscoverer
Real task was actually Callable: 1
Real task was actually Runnable: 2
Real task was actually Callable: 2
Real task was actually Runnable: 3
Real task was actually Callable: 3
Real task was actually Runnable: 4
Real task was actually Callable: 4

Short and sweet newsletter I hope? :-) Sent from Athens International Airport.

Kind regards


Tips and Tricks Articles Related Java Course

Extreme Java - Concurrency and Performance for Java 8
Extreme Java - Advanced Topics for Java 8
Design Patterns
In-House Courses

© 2010-2016 Heinz Kabutz - All Rights Reserved Sitemap
Oracle and Java are registered trademarks of Oracle and/or its affiliates. Other names may be trademarks of their respective owners. is not connected to Oracle, Inc. and is not sponsored by Oracle, Inc.