Runnable is default abstraction for creating a task in Java. It has a single method run() that accepts no arguments and returns no value, nor it can throw any checked exception. To overcome these limitations, Java 5 introduced a new task abstraction through Callable [javadoc ] interface.
public interface Callable<V>{Evident from the Callable interface shown above, call() method can return an Object, or more specifically any generic type. Like Runnable, Callable is also designed to be executed by threads. But you can't directly pass a Callable into Thread for execution. Check below snippet :
V call() throws Exception;
}
Callable task = new Callable(){
public Integer call(){
System.out.println("inside call method");
return 1;
}
};
The last line in above code will not compile. It gives below compilation error message:
"The constructor Thread(Callable) is undefined".
It tells Thread can't take a Callable argument.
Recall that Thread class implements Runnable interface, and it has been with Java since version 1.0, whereas Callable got added to the language in version 5.0 (or 1.5) only.
Running a Callable Task
Passing Callable into Thread for execution is out of question. Java SE 5 provides ExecutorService to execute the Callable object. The service accepts a Callable object.
<T> Future<T> submit(Callable<T> task);
As above definition shows, submitting a Callable object to ExecutorService returns Future object. Future represents the life cycle of a task and is discussed below:
Callable<List<T>> task = new Callable<List<T>>(){
public List<T> call(){
List<T> results = new ArrayList<T>();
//computation
return results;
}
};
ExecutorService es = Executors.newSingleThreadExecutor();
Future<List<T>> future = es.submit(task);
List<T> data = future.get();
System.out.println("List Data :"+ data);
The get() method of Future blocks, until the task is completed. This is equivalent to join() (i.e. t.join()) in normal thread case.
A closer look at Future
Future represents the life cycle of a task and provides methods to test whether the task has completed or been canceled, retrieve the result, and cancel the task. The behavior of get method depends on the state of the task (yet to start, completed, running). Get method returns immediately or throws Exception if the task has already completed. If the task is not completed then it blocks until the task completes.
Straight from Java Doc :
Future class methods |
Future represents the result of an asynchronous computation. Methods are provided to check if the computation is complete, to wait for its completion, and to retrieve the results of the computation. The results can only be retrieved using method get when the computation has completed, blocking if necessary until it is ready. Cancellation is performed by the cancel method. Additional methods are provided to determine if the task completed normally or was canceled. Once a computation has completed, the computation cannot be canceled. If you would use a Future for the sake of cancellability but not provide a usable result, you can declare the type of the form Future<?> and return null as a result of the underlying task.
Related Post : Executor Framework in Java
----
post your comments/questions below !!!