90

I tried hard but didn't find any article or blog which clearly compares ListenableFuture and CompletableFuture, and provides a good analysis.

So if anyone can explain or point me to such a blog or article, it will be really good for me.

tom
  • 2,735
  • 21
  • 35
Ashutosh Jha
  • 1,465
  • 1
  • 17
  • 28
  • 1
    A blog from gauva team about [ListenableFuture](https://github.com/google/guava/wiki/ListenableFutureExplained) – TongChen Aug 25 '20 at 02:11

2 Answers2

82

Both ListenableFuture and CompletableFuture have an advantage over its parent class Future by allowing the caller to "register" in one way or another a callback to be called when the async action has been completed.

With Future you can do this:

ExecutorService executor = ...;
Future f = executor.submit(...);
f.get();

f.get() gets blocked until the async action is completed.

With ListenableFuture you can register a callback like this:

ListenableFuture listenable = service.submit(...);
    Futures.addCallback(listenable, new FutureCallback<Object>() {
                @Override
                public void onSuccess(Object o) {
                    //handle on success
                }

                @Override
                public void onFailure(Throwable throwable) {
                   //handle on failure
                }
            })

With CompletableFuture you can also register a callback for when the task is complete, but it is different from ListenableFuture in that it can be completed from any thread that wants it to complete.

CompletableFuture completableFuture = new CompletableFuture();
    completableFuture.whenComplete(new BiConsumer() {
        @Override
        public void accept(Object o, Object o2) {
            //handle complete
        }
    }); // complete the task
    completableFuture.complete(new Object())

When a thread calls complete on the task, the value received from a call to get() is set with the parameter value if the task is not already completed.

Read about CompletableFuture

Uvuvwevwevwe
  • 971
  • 14
  • 30
Livia Moroianu
  • 906
  • 7
  • 6
  • 25
    In other words... ListenableFuture is a well thought out clean interface, while CompletableFuture (and the CompletionStage interface since it exposes `toCompletableFuture`) is dangerous because it exposes `complete` methods. Yet another example of the not-very-well-thought-out garbage that we've come to expect from Oracle. – Shadow Man Feb 24 '17 at 21:39
  • `CompletionStage` would have been good if it extended `Future` and did not expose `toCompletableFuture`. And then they could have then named it something meaningful, like "ChainableFuture". – Shadow Man Feb 24 '17 at 21:57
  • 7
    `Future` and `ListenableFuture` are interfaces while `CompletableFuture` is a class that implements `Future` – cozyconemotel Aug 21 '17 at 10:29
  • @ShadowCreeper [link](http://cs.oswego.edu/pipermail/concurrency-interest/2013-July/011496.html) they did have that discussion and came up with toCompletableFuture so that you cannot just cast it back to CompletableFuture and keep using the Pull and Push mechanisms – motaa Nov 30 '17 at 16:20
  • 3
    @motaa they chose poorly. The fluent methods break if you just wrap your `CompletableFuture` and override it to throw an exception on `toCompletableFuture` (as the discussion at your link suggests) since most of those fluent methods actually call the `toCompletableFuture` method to do their stuff. `ListenableFuture` has much less noise, and less "dangerous" stuff. – Shadow Man Nov 30 '17 at 23:04
  • @ShadowCreeper in that context I do agree with you :) – motaa Dec 01 '17 at 11:58
  • ListenableFuture is not part of the java docu right? Sorry but what class are you then talking about? – Anna Klein Apr 02 '18 at 10:35
  • 1
    @AnnaKlein ListenableFuture is part of Google's Guava that has significant impact on shaping Java 8 APIs from Supplier/Consumers to Optional or ListenableFutures (it helped dev a lot in Java 6/7 Days). I still like Optional from guava over Java 8. – prash May 10 '18 at 09:32
  • Guava does provide Futures#transform and Futures#transformAsync which allow manipulation of Futures once they complete via callback chaining – Kurru Aug 26 '21 at 02:04
-3

Guava AbstractFuture has its limitations:

  1. Listener is lists, but usually only 1 used - overkill. If multiple listeners are needed, handle it inside the next stage, or think about messaging.

  2. setException set return value as Exception, so user has to use instanceof to differentiate Exception or not at get() like guava AbstractFuture did.

  3. In Future pipeline, too many layers addListener() make code hard to read.

I prefer CompletableFuture.supply().thenApply().thenAccept().handle()

vakio
  • 3,134
  • 1
  • 22
  • 46
simple
  • 1
  • 1