Pages

Label

Rabu, 30 Januari 2019

Future and FutureTask in Java

Hello Guys !!! Hope You all doing well. 
Today i a going to discuss Future task in Java multitasking concept. 
Future and FutureTask are available in java.util.concurrent package from Java 1.5.

Future is and interface and FutureTask is an implementation or RunnableFuture, which can be used as a Runnable interface, thus, can be passed to ExecutorService.

One of the simplest examples of using Future is working with Thread pools. 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 result of computation.

In simple words, Future allows any method to return immediately, with promise of result being available in future. By using this technique our main thread can do other things while waiting for certain task to be completed.

In Android Jobscheduler and jobService are based on it. You can find more detail from my previous blog.
Important points Future and FutureTask in Java
  1. Future is a base interface and defines 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 written as Future<V>, where V denotes value.
  3. Future provides get() method to get result, which is blocking method and blocks until result is available to Future.
  4. Future interface also defines cancel() method to cancel task.
  5.  isDone() and isCancelled() method is used to query Future task states. isDone() returns true if task is completed and 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 cancelled before its completion.
  6. Future has four sub interfaces, 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.
  7. FutureTask and SwingWorker are two well known implementation of 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 you, i.e. when you submit() Callable or Runnable object. You can also created it manually.
  9. FutureTask is normally used to wrap Runnable or Callable object and submit them to ExecutorService for asynchronous execution.

Future and FutureTask Example - Java
  • First we have created a FutureTask which is nothing but a nested static class which implements Callable interface.
  • In this method we call our factorial method to calculate factorial of a number.
  • To make this method long-running, we have also introduced a small sleep duration.
  • When we submit this task with job of calculating factorial of a huge number like 100000, ExecutorService returns a Future object, which holds long value, return type of call method in our case. Future object returned by the submit() method is also an instance of FutureTask
  • we can check whether task is completed or not using isDone() method.
From output, we can see that main thread returns immediately.
Since we have used get() method once task is completed, it doesn't block and return result immediately. Download Source Code


package com.sls.example1;
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;
import java.util.logging.Level;
import java.util.logging.Logger;
import junit.framework.Test;
public class FutureThreadExample {

    private static final ExecutorService threadpool = Executors.newFixedThreadPool(3);

    public static void main(String[] args) throws InterruptedException, ExecutionException {

        FactorialCalculator task = new FactorialCalculator(10); 
        System.out.println("Submitting Task ..."); 

        Future future = threadpool.submit(task);
        System.out.println("Task is submitted"); 

        while (!future.isDone()) {
            System.out.println("Task is not completed yet...."); 
            Thread.sleep(1); //sleep for 1 millisecond before checking again 
            } 

        System.out.println("Task is completed, let's check result"); 
        long factorial = (long) future.get(); 
        System.out.println("Factorial of 1000000 is : " + factorial); 
        threadpool.shutdown();

        }

    }

    class FactorialCalculator implements Callable {
        private final int number; 

        public FactorialCalculator(int number) { 
            this.number = number; 
            }

        @Override
        public Object call() throws Exception {
            long output = 0;
            try {
                output = factorial(number);
            } catch (InterruptedException ex) {
                Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
            }
            return output;
        }

        private long factorial(int number) throws InterruptedException {
            if (number < 0) {
                throw new IllegalArgumentException("Number must be greater than zero");
            }
            long result = 1;
            while (number > 0) {
                Thread.sleep(1); // adding delay for example
                result = result * number;
                number--;
            }
            return result;
        }

    }

Thanks Happy Coding!!!

0 komentar:

Posting Komentar

 
[tutup]