Social Groups

A Future interface implementation object is used to represent the result of an asynchronous computation in Java concurrency.

A Future interface provides methods to check if the computation is complete, to wait for its completion, and to retrieve the result of the computation. The result is retrieved using Future's get method when the computation has completed, and it blocks until it is completed. Cancellation is performed by the cancel method (cancel(boolean mayInterruptIfRunning)). The cancel method returns true if the task was cancelled, and will not have any effect and return false if the task has already completed or already cancelled, or could not be cancelled for some reason. After a successful cancel, tasks that have not started will not run. The mayInterruptIfRunning parameter determines whether already started tasks should be interrupted in an attempt to stop the task. Additional methods isDone() and isCancelled()determine if the task completed normally or was cancelled.

Once a computation has completed, the computation cannot be cancelled. If a task completes by throwing an exception, corresponding Future.get rethrows it wrapped in an ExecutionException; and if it was cancelled, Future.get throws CancellationException. If Future.get throws ExecutionException, the underlying exception can be retrieved with getCause. The submit method in the ExecutorService return a Future when you submit a Runnable or a Callable. The Runnable or Callable is safely published from the submitting thread to the thread that will execute the task. The result value for a Future is also safely published from the thread in which it was computed to any thread that retrieves it via get.

FutureTask is an implementation of Future. You can explicitly instantiate a FutureTask for a given Runnable or Callable. A FutureTask can be submitted to an Executor for execution as FutureTask implements Runnable. FutureTask can also be executed directly by calling its run method. Once a FutureTask enters the completed state, it stays in that state forever. If the task is completed. FutureTask constructors can accept either Callable or Runnable.

Callable is similar to Runnable, but it can return result unlike Runnable. Callable can be in one of three states: waiting to run, running, or completed. Completion can be normal completion, cancellation, and exception. Tasks described by Callable can throw checked and unchecked exceptions, and any code can throw an Error. When used with Future, anything thrown from the Callable is wrapped in an ExecutionException and re-thrown from Future.get. The code that calls get must deal with the possibility of ExecutionException (and the unchecked CancellationException). The cause of the ExecutionException is returned as a Throwable and can be retrieved with getCause method.

Example: FutureTaskExample.java

import java.util.concurrent.Callable;

import java.util.concurrent.ExecutionException;

import java.util.concurrent.FutureTask;

public class FutureTaskExample {

public static void main(String[] args) {

FutureTask<String> future = new FutureTask<>(new CallableTask());

//Cancelling code before run

/*boolean b = future.cancel(true);

System.out.println("Cancelled="+b);*/

future.run();

//Cancelling code after run

/*boolean b = future.cancel(true);

System.out.println("Cancelled="+b);*/

try {

String result = future.get();

System.out.println("Result="+result);

} catch (InterruptedException | ExecutionException e) {

System.out.println("EXCEPTION!!!");

e.printStackTrace();

}

}

}

class CallableTask implements Callable<String>{

@Override

public String call() throws Exception {

System.out.println("Executing call() !!!");

/*if(1==1)

throw new java.lang.Exception("Thrown from call()");*/

return "success";

}

}

Output will be:

Executing call() !!!

Result=success

TO DO (To understand more):

Remove the block comment (/*…*/) on the cancel code before run. You will get Cancelled=true followed by CancellationException. The run() method don’t have any effect and Future.get throws the CancellationException.

Comment the try-catch block with Future.get. You will get Cancelled=true, but no exception. The run() method don’t have any effect and Future.get was throwing the CancellationException.

Comment the cancel code before run as before, uncomment try-catch block with Future.get as before, and uncomment cancel code after run. You will see Executing call() !!! followed by Cancelled=false. Calling cancel on already done task has no effect, it just return false.

Comment the cancel code before/after run as before, and uncomment the exception code block comment (/*…*/) in the call method of CallableTask class. You will see Executing call() !!!, EXCEPTION!!!, and java.util.concurrent.ExecutionException: java.lang.Exception: Thrown from call()…

Exception is thrown only when Future.get is called, even if it is thrown from within call. If no call to Future.get, no exception will be thrown out. Comment the try-catch block with Future.get. You will see no exception.

You are here

This is a personal technical blog where we share our understanding on various concepts and is neither an official page or documentation for the products described here, nor the official views of the companies we work with.

Keywords used in this website are trademarks of their respective owners. This website is not affiliated with Oracle™ and/or any of the JEE frameworks like Spring™, Struts™, Hibernate™ and JSF™.

All contents and materials are provided freely without any warranty or liability and nothing within the site should be considered as professional advice. In any doubt, please ask, and we will try to help you based on our knowledge. Please let us know if you feel anything is not right here (including any copyright violation) and we will act upon it as fast as we can.