Java Concurrency and Multithreading, Part 3: The FutureTask Class and the Callable Interface

Last time we looked at the Thread class and the Runnable interface, but that pairing has one problem: no return value. If we want the thread to hand a value back, we need FutureTask and Callable, which is what this post covers.

Series index: Java Intermediate/Advanced Programming: article index

Disclaimer up front: everything in this series is my own understanding of the subject, typed out by hand. It may well contain mistaken views or misunderstandings. Use it as reference only, and corrections are welcome.

Last time we looked at the Thread class and the Runnable interface, but that pairing has one problem: no return value. If we want the thread to hand a value back, we need FutureTask and Callable, which is what this post covers.

All demo code for this series is public at https://github.com/renfei/demo/tree/master/java/ConcurrentDemo

FutureTask

FutureTask provides the basic implementation of Future: methods to start and cancel a task, to query whether it has completed, and to retrieve its result. The result is only obtainable once the task completes; afterwards the task cannot be restarted or cancelled, except by calling runAndReset.

FutureTask also implements Runnable, so you can hand it to Thread and run it. Because it implements both Runnable and Future, FutureTask is essentially a thread that can return a value.

The class relationships:

FutureTask class diagram

The Callable Interface

When instantiating FutureTask you pass in a class implementing Callable. Callable declares call(), and FutureTask gets its return value by calling our call() method.

Let’s write some code and feel it.

First, a class implementing Callable. Its constructor takes a name, prints ten times, and returns 100 as its result:

class MyCallable implements Callable<Integer> {
    private String myName;
    public MyCallable(String name) {
        this.myName = name;
    }
    @Override
    public Integer call() throws Exception {
        for (int i = 0; i < 10; i++) {
            System.out.println(this.myName + " :: printing i = " + i);
        }
        return 100;
    }
}

Then instantiate the thread, start it, and get the return value:

FutureTask<Integer> futureTask = new FutureTask<>(new MyCallable("Our Callable implementation"));
Thread threadA = new Thread(futureTask);
threadA.start();
System.out.println("main got the returned value: " + futureTask.get());

Full demo source: https://github.com/renfei/demo/blob/master/java/ConcurrentDemo/src/main/java/net/renfei/demo/concurrent/CallableDemo.java