Close

Java - Future Interface

[Updated: Dec 7, 2018, Created: Oct 3, 2018]

The interface java.util.concurrent.Future represents the result of an asynchronous computation.

The future interface snippet:

package java.util.concurrent;
 ....
public interface Future<V> {
 boolean cancel(boolean mayInterruptIfRunning);//Attempts to cancel execution of this task
 boolean isCancelled();//Returns true if this task has been cancelled
 boolean isDone();//Returns true if this task completed.
 V get() throws InterruptedException, ExecutionException;//waits and returns the results
 V get(long timeout, TimeUnit unit)//waits for at most the given time and returns the results if available
        throws InterruptedException, ExecutionException, TimeoutException;
}

The instance of this interface is returned by following methods of ExecutorService:

<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);
Future<?> submit(Runnable task);
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException;
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)

None of the above methods blocks for the task to complete but they return immediately. The returned Future object can be used later to query the result.

Examples

Future.get()

package com.logicbig.example;

import java.util.concurrent.*;

public class FutureGetExample {
  public static void main(String[] args) throws ExecutionException, InterruptedException {
      ExecutorService es = Executors.newSingleThreadExecutor();
      Future<Long> futureResult = es.submit(new Callable<Long>() {
          @Override
          public Long call() throws Exception {
              //simulating long running task
              Thread.sleep(1000);
              System.out.println("returning");
              return ThreadLocalRandom.current().nextLong();
          }
      });
      System.out.println("callable submitted");
      //after doing other stuff
      System.out.println("waiting for result");
      Long result = futureResult.get();//blocks until the task finishes
      System.out.println(result);
      es.shutdown();
  }
}
callable submitted
waiting for result
returning
-4447662861767260382

Future.cancel()

package com.logicbig.example;

import java.util.concurrent.*;

public class FutureCancelExample {
  public static void main(String[] args) throws ExecutionException, InterruptedException {
      ExecutorService es = Executors.newSingleThreadExecutor();
      Future<Long> futureResult = es.submit(new Callable<Long>() {
          @Override
          public Long call() throws Exception {
              //simulating long running task
              Thread.sleep(1000);
              System.out.println("returning");
              return ThreadLocalRandom.current().nextLong();
          }
      });
      System.out.println("callable submitted");
      //after doing other stuff
      System.out.println("canceling task");
      boolean c = futureResult.cancel(true);
      System.out.println(c);
      //following will throw java.util.concurrent.CancellationException
      //Long result = futureResult.get();
      es.shutdown();
  }
}
callable submitted
canceling task
true

Following shows the use of Future.cancel(false) which allows the task to complete.

package com.logicbig.example;

import java.util.concurrent.*;

public class FutureCancelExample2 {
  public static void main(String[] args) throws ExecutionException, InterruptedException {
      ExecutorService es = Executors.newSingleThreadExecutor();
      Future<Long> futureResult = es.submit(new Callable<Long>() {
          @Override
          public Long call() throws Exception {
              System.out.println("task started and running");
              Thread.sleep(1000);
              System.out.println("returning result");
              return ThreadLocalRandom.current().nextLong();
          }
      });
      Thread.sleep(100);
      System.out.println("callable submitted");
      //after doing other stuff
      System.out.println("canceling task");
      boolean c = futureResult.cancel(false);
      System.out.println(c);
      //following will still throw java.util.concurrent.CancellationException
      //Long result = futureResult.get();
      es.shutdown();
  }
}
task started and running
callable submitted
canceling task
true
returning result

Using Future without usable result

If we want to use Future for the sake of cancellability but not provide a usable result, we can declare types of the form Future<?> which will return null as a result of the underlying task.

public class FutureNoResultsExample {
  public static void main(String[] args) throws ExecutionException, InterruptedException {
      ExecutorService es = Executors.newSingleThreadExecutor();
      Future<?> futureResult = es.submit(new Runnable() {
          @Override
          public void run() {
              //simulating long running task
              try {
                  Thread.sleep(1000);
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
          }
      });
      System.out.println("callable submitted");
      //after doing other stuff
      System.out.println("getting result");
      Object o = futureResult.get();
      System.out.println(o);
      es.shutdown();
  }
}
callable submitted
getting result
null

Future.isDone()

This method returns true if task has completed.

public class FutureIsDoneExample {
  public static void main(String[] args) throws ExecutionException, InterruptedException {
      ExecutorService es = Executors.newSingleThreadExecutor();
      Future<Long> futureResult = es.submit(new Callable<Long>() {
          @Override
          public Long call() throws Exception {
              //simulating long running task
              Thread.sleep(1000);
              System.out.println("returning");
              return ThreadLocalRandom.current().nextLong();
          }
      });

      System.out.println("callable submitted");
      while(!futureResult.isDone()) {
          //do some other stuff
        Thread.sleep(10);
      }
      System.out.println("task done");
      Long result = futureResult.get();//will not block
      System.out.println(result);
      es.shutdown();
  }
}
callable submitted
returning
task done
-1773366881493053319

Example Project

Dependencies and Technologies Used:

  • JDK 11
  • Maven 3.5.4

Asynchronous computation result via Future interface Select All Download
  • java-future-interface-examples
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • FutureGetExample.java

    See Also