Guava ListenableFuture intro

13 09 2015

ListenableFuture is an abstraction to run asynchronous tasks in highly concurrent apps. It allows you to start a task, register callbacks and leave it to run and complete in separate thread. To fully explain it, let’s start with standard JDK Future.

JDK Fututre

JDK Future is dedicated to use with long running tasks. It returns you a Promise that may or may not yet have completed getting the result. The idea is to:

  1. execute the long running task
  2. assign the result to the Promise immediately (although the promise is not yet completed)
  3. perform any other operations you need (if any)
  4. few lines of code later you get the result of the Promise. If it already completed – you get the result immediately, else you wait until it completes.
  5. The effect is you could execute operations (from point 3.) while the Future was still evaluating, not blocking your thread. The thread is blocked already in point 4 where you potentially wait for the result blocking the main thread.


Guava’s ListenableFuture adds one more method to the Future interface:

addListener(Runnable, Executor)

Thanks to it you omit the point 5: waiting for Promise to fulfil. You just:

  1. Start the long running task and provide it with a success and failure callback
  2. evaluate the result in a callback, put the whole logic in there. It gets executed when task completes.

It is valuable in highly concurrent apps since its fully event driven notion.

The demo

My demo will show two ways of handling long running tasks.

The long runnning task emulation

Assume that I have long running method I need to execute in separate thread pool. To make it simple my task is blocking thread for five seconds by sleep():

public String executeLongRunningTask() throws InterruptedException {
    System.out.println( + " Starting evaluating long running tasks...");
    return "Evaluation finished at " +;

Main thread blocking execution

This is the simplest way to execute such a task:

private static void runBlockingOperationDemo() throws InterruptedException {
    System.out.println( + " Hello future!");
    final ListenableFutureDemo demo = new ListenableFutureDemo();
    String result = demo.executeLongRunningTask();
    System.out.println( + " Main method completed with result: " + result);

This way causes the main thread to wait until long running task execution completes (watch the timestamps):

21:19:37.305 Hello future!
21:19:37.318 Starting evaluating long running tasks...
21:19:42.319 Main method completed with result: Evaluation finished at 21:19:42.319

Note that between task execution start and main method execution completion there is a span of 5 seconds long.

ListenableFuture with callbacks

Let’s see how the app behaves when ListenableFuture is in action. The steps are:

  1. create executor service to submit future tasks
  2. execute non-blocking task in executor’s thread pool
  3. add success and failure handler that will be fired on task completion
private static void runListenableFutureDemo() {
    System.out.println( + " Hello future!");

    final ListenableFutureDemo demo = new ListenableFutureDemo();

    //create executor service to submit all future tasks
    ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));

    //execute non-blocking task
    ListenableFuture<String> listenableFuture = service.submit(new Callable<String>() {
        public String call() throws Exception {
            return demo.executeLongRunningTask();

    //add success and failure handler to listenableFuture object
    Futures.addCallback(listenableFuture, new FutureCallback<String>() {
        public void onSuccess(String result) {
            System.out.println( + " Task completed successfuly with result: " + result);

        public void onFailure(Throwable t) {
            System.out.println( + " Task failed with result: " + t.getMessage());

    System.out.println( + " Main method completed but the result is still being calculated...");

The console output presents how it works (mind the timestamps and messages order):

21:23:09.623 Hello future!
21:23:09.663 Starting evaluating long running tasks...
21:23:09.685 Main method completed but the result is still being calculated...
21:23:14.668 Task completed successfuly with result: Evaluation finished at 21:23:14.667

Note that the main method has completed before the long running task is complete. The task execution completed 5 seconds later. Main thread did not have the task result. The result is known in success handler in callback. Pure asynchronous programming.

The demo source code

Get the code from my GitHub:



One response

25 09 2015
Java 8 CompletableFuture intro | Looks OK!

[…] CompletableFuture seems to be very legit response for the need addressed by Guava’s ListenableFuture (see my intro here). […]

Give Your feedback:

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: