Appearance
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.