Monday, 15 May 2017

Future and FutureTask in Java

Future and FutureTask allows us to write asynchronous code. Future is a general concurrency abstraction, also known as a promise, which promises to return a result in future.

In asynchronous programming, main thread doesn't wait for any task to finished, rather it hands over the task to workers and move on. One way of asynchronous processing is using callback methods. Future is another way to write asynchronous code. By using Future and FutureTask, we can write a method which does long computation but returns immediately. Those methods, instead of returning a result, return a Future object. We can later get the result by calling Future.get() method, which will return an object of type T, where T is what Future object is holding.

Future and FutureTask are available in java.util.concurrent package from Java 1.5. Future is interface and FutureTask is an implementation.

FutureTask<V> extends Object implements RunnableFuture<V>
public interface RunnableFuture<V> extends Runnable, Future<V>

Example of Future and FutureTask
Working with Thread pools is the best example of Future. When we submit a long running task to ExecutorService, it returns a Future object immediately. This Future object can be used to query task completion and getting the result of computation.

In below-given example, ExecutorService returns a Future object, which holds long value, the return type of call method in our case. Later, we check whether the task is completed or not using isDone() method. From the output, we can see that main thread returns immediately. Since we have used get() method once the task is completed, it doesn't block and return the result immediately.

By the way, the Future object returned by the submit() method is also an instance of FutureTask.

package com.thread;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * Java program to show how to use Future in Java.
 * Future allows to write asynchronous code in Java, where
 * Future promises result to be available in future.
 **/
public class FutureTaskTest {

     private static final ExecutorService executorPool = Executors.newFixedThreadPool(3);
    
     public static void main(String args[]) throws InterruptedException, ExecutionException {
          
           FibonacciCalculator task = new FibonacciCalculator(15);
          
           System.out.println("Submitting Task ...");
           Future<Long> future = executorPool.submit(task);
          
           System.out.println("Task is submitted");

           while (!future.isDone()) {
                System.out.println("Task is still running... isDone()");
               
                /* sleep for 1000 millisecond before checking again */
                Thread.sleep(1000);
           }
          
           System.out.println("Task is completed, result is");
           long fibonacci = future.get();
          
           System.out.println("Fibonacci value of 100 is : get() " + fibonacci);
          
           /* Shut down the executor service. */
           executorPool.shutdown();
     }
    
     /**
      * Callble Task
      * @author rajesh
      */
     private static class FibonacciCalculator implements Callable<Long> {
          
           private final int number;
           public FibonacciCalculator(int number) {
                this.number = number;
           }

           @Override
           public Long call() {
                long output = 0;
                try {
                     output = fibonacci(number);
                } catch (InterruptedException ex) {
                     System.err.println("error");
                }
                return output;
           }

           private long fibonacci(int number) throws InterruptedException {
                if (number < 0) {
                     throw new IllegalArgumentException("Non zero number is required.");
                }
               
                long result = 1;
               
                /* Adding delay for example. */
                Thread.sleep(2);
               
                if(number==0 || number==1 || number==2) {
                     result = number;
                } else {
                     result = fibonacci(number-1)+fibonacci(number-2);
                }
                return result;
           }
     }
}


Key points Future and FutureTask

1. Future is a base interface and defines an abstraction of an object which promises result to be available in future while FutureTask is an implementation of the Future interface.

2. Future is a parametric interface and type-safe (=using generics) written as Future<V>, where V denotes value.

get():
3. Future provides get() method to get a result, which is blocking method and blocks until the result is available to Future.

cancel():
4. Future interface also defines cancel() method to cancel the task.

isDone() and isCancelled():
5. isDone() and isCancelled() method is used to query Future task states.
isDone() returns true if the task is completed and a result is available to Future. If you call get() method, after isDone() returned true then it should return immediately. On the other hand, isCancelled() method returns true, if this task is canceled before its completion.

6. There are four subinterfaces of Future, each with additional functionality e.g. Response, RunnableFuture, RunnableScheduledFuture, and ScheduledFuture. RunnableFuture also implements Runnable and successful finish of run() method cause completion of this Future.

FutureTask and SwingWorker:
7. FutureTask and SwingWorker are two well-known implementations of the Future interface. FutureTask also implements RunnableFuture interface, which means this can be used as Runnable and can be submitted to ExecutorService for execution.

8. Though most of the time ExecutorService creates FutureTask for us, i.e. when we submit() Callable or Runnable object. We can also create it manually.

9. FutureTask is normally used to wrap the Runnable or Callable object and submit them to ExecutorService for asynchronous execution.


No comments:

Post a Comment

Related Posts Plugin for WordPress, Blogger...