Sunday, June 30, 2013

Callable and Future in Java

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>{
     V call() throws Exception;
}
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 :

         Callable task = new Callable(){
  public Integer call(){
System.out.println("inside call method");
   return 1;
}
        };
Thread t = new Thread(task);    //doesn't compile

Last line in above code will not compile. It gives below compilation error message:  
"The constructor Thread(Callable) is undefined".
It tell, 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 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 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.

Closer look at Future

Future represents the life cycle of a task and provides methods to test whether the task has completed or been cancelled, retrieve the result, and cancel the task. The behavior of get method depends on the state of 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. 
Future class methods
Straight from Java Doc :
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 cancelled. Once a computation has completed, the computation cannot be cancelled. If you would to use a Future for the sake of cancellability but not provide a usable result, you can declare type of the form Future<?> and return null as a result of the underlying task.

----
post your comments/questions below !!!

1 comment:

  1. When someone writes an piece of writing he/she retains thhe plan off a user in his/her mind that
    how a user caan know it. Thus that's why this paragraph is perfect.
    Thanks!

    Here iss my web-site free eu domains

    ReplyDelete