While Runnable
provides a means to wrap code to be executed in a different thread, it has a limitation in that it cannot return a result from the execution. The only way to get some return value from the execution of a Runnable
is to assign the result to a variable accessible in a scope outside of the Runnable
.
Callable
was introduced in Java 5 as a peer to Runnable
. Callable
is essentially the same except it has a call
method instead of run
. The call
method has the additional capability to return a result and is also allowed to throw checked exceptions.
The result from a Callable task submission is available to be tapped via a Future
Future
can be considered a container of sorts that houses the result of the Callable
computation. Computation of the callable can carry on in another thread, and any attempt to tap the result of a Future
will block and will only return the result once it is available.
Callable Interface
public interface Callable<V> {
V call() throws Exception;
}
Future
interface Future<V> {
V get();
V get(long timeout, TimeUnit unit);
boolean cancel(boolean mayInterruptIfRunning);
boolean isCancelled();
boolean isDone();
}
Using Callable and Future example:
public static void main(String[] args) throws Exception {
ExecutorService es = Executors.newSingleThreadExecutor();
System.out.println("Time At Task Submission : " + new Date());
Future<String> result = es.submit(new ComplexCalculator());
// the call to Future.get() blocks until the result is available.So we are in for about a 10 sec wait now
System.out.println("Result of Complex Calculation is : " + result.get());
System.out.println("Time At the Point of Printing the Result : " + new Date());
}
Our Callable that does a lengthy computation
public class ComplexCalculator implements Callable<String> {
@Override
public String call() throws Exception {
// just sleep for 10 secs to simulate a lengthy computation
Thread.sleep(10000);
System.out.println("Result after a lengthy 10sec calculation");
return "Complex Result"; // the result
}
}
Output
Time At Task Submission : Thu Aug 04 15:05:15 EDT 2016
Result after a lengthy 10sec calculation
Result of Complex Calculation is : Complex Result
Time At the Point of Printing the Result : Thu Aug 04 15:05:25 EDT 2016
Other operations permitted on Future
While get()
is the method to extract the actual result Future has provision
get(long timeout, TimeUnit unit)
defines maximum time period during current thread will wait for a result;cancel(mayInterruptIfRunning)
. The flag mayInterrupt
indicates that task should be interrupted if it was started and is running right now;isDone()
;isCancelled()
.