The result of an asynchronous computation is called Future and more specifically, it has this name because it (the result) will be completed at a later point of time in the future. Future object is created when an asynchronous task has been created. There are many methods that are provided that help to retrieve the result (using get methods(which is the only way of retrieval)), cancellation using the cancel method and methods that check whether the task was completed successfully or was canceled.
The main advantage that Future gives is that it enables us to execute other process simultaneously whilst waiting for the main task that was embedded in the Future to be completed. That means that when we are faced against large computations, using Future would be a good idea.
Methods
- boolean cancel(boolean mayInterruptIfRunning)
- V get()
- V get(long timeout, TimeUnit unit)
- this is different than the get method above as in this one there is a timeout specified that will be the wait criteria
- boolean isCancelled()
- boolean isDone()
Basic Implementation of Future using get(timeout, unit)
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; public class FutureDemo { public static void main(String[] args) { ExecutorService executorService = Executors.newSingleThreadExecutor(); Future<String> future = executorService.submit(() -> { Thread.sleep(5000); return "Done"; }); try { while(!future.isDone()) { System.out.println("Task completion in progress..."); Thread.sleep(500); } System.out.println("Task completed!"); String result = future.get(3000, TimeUnit.MILLISECONDS); // that's the future result System.out.println(result); executorService.shutdown(); } catch (InterruptedException e) { } catch (ExecutionException e) { } catch (TimeoutException e) { // this will be thrown if the task has not been completed within the specified time future.cancel(true); // if this task has not started when cancel is called, this task should never run future.isDone(); // will return true future.isCancelled(); // will return true } } }
Output:
Task completion in progress... Task completion in progress... Task completion in progress... Task completion in progress... Task completion in progress... Task completion in progress... Task completion in progress... Task completion in progress... Task completion in progress... Task completion in progress... Task completed! Done
Breakdown
Calling the submit() method on ExecutorService, returns a Future. Now that we have a Future, we can call the methods above. What you should pay particular attention to, however, is the fact that it is printing “Task completion in progress…” while the submitted task is “running”.
The TimeoutException catch will be thrown if the task has not been completed within the specified time (as the comment suggests).