Skip to content
On this page

Future

When executing multiple tasks, using the thread pool provided by the Java standard library is very convenient. We only need to implement the Runnable interface for the tasks we submit, and the thread pool will execute them:

java
class Task implements Runnable {
    public String result;

    public void run() {
        this.result = longTimeCalculation(); 
    }
}

The Runnable interface has a problem: its method does not return a value. If a task needs to return a result, we have to store it in a variable and provide an extra method to read it, which is quite inconvenient. Therefore, the Java standard library also provides a Callable interface, which has a return value compared to the Runnable interface:

java
class Task implements Callable<String> {
    public String call() throws Exception {
        return longTimeCalculation(); 
    }
}

Moreover, the Callable interface is a generic interface, allowing us to specify the type of the result returned.

Now the question is, how can we obtain the result of asynchronous execution?

If we take a closer look at the ExecutorService.submit() method, we will see that it returns a Future type. An instance of the Future type represents an object that can get the result in the future:

java
ExecutorService executor = Executors.newFixedThreadPool(4); 
// Define the task:
Callable<String> task = new Task();
// Submit the task and obtain a Future:
Future<String> future = executor.submit(task);
// Get the result of asynchronous execution from the Future:
String result = future.get(); // May block

When we submit a Callable task, we also get a Future object at the same time. Then, at some point in the main thread, we can call the get() method of the Future object to obtain the result of the asynchronous execution. If the asynchronous task is already completed when we call get(), we will get the result immediately. If the asynchronous task is not yet finished, get() will block until the task completes and returns the result.

A Future<V> interface represents a result that may be returned in the future and defines the following methods:

  • get(): Gets the result (may wait).
  • get(long timeout, TimeUnit unit): Gets the result but only waits for the specified time.
  • cancel(boolean mayInterruptIfRunning): Cancels the current task.
  • isDone(): Checks if the task is completed.

Exercise

Use Future to get the result of asynchronous execution.

Summary

Submitting a Callable task to a thread pool allows us to obtain a Future object;

We can use Future to get the result at some point in the future.

Future has loaded