1

I have tried complex usecases which can be done by CompletableFuture can be done by ExecutorService as well. That includes, handling exceptions as well.

The only difference I can see between them is, CompletableFuture gives better readability and convenience during coding.

Is there any practical advantage / use-case that one can solve using CompletableFuture, but not with ExecutorService?

Manikandan Kbk
  • 131
  • 1
  • 8
  • Why do you think they're _different_? (But the answer is generally going to be non-blocking waiting on futures.) – Louis Wasserman Jul 10 '21 at 20:52
  • Googling the title of your question verbatim gives 4 pages on the first 10 results which are either other stack overflow questions with answers, or blogs/posts covering the same topic in (varying levels of) detail. – BeUndead Jul 10 '21 at 21:01

2 Answers2

2

Imagine the simple case, you do action A, when it is complicated, do B with the result of A operation - be that a Throwable or a valid result. Add to that that there is no CompletableFuture yet, and you do not want to block. Is it doable with Futures only? Well, yes. Is it painful to achieve? Very.

Do not get fooled by the "simplicity" of its API. In your previous question you already saw what not specifying an ExecutorService to some actions does. There are many, many more subtle things that comes with the package of that "simplicity".

The non-blocking capabilities of CompletableFuture made it highly usable and highly adopted by the developers. Not only us, usual developers, but the jdk ones too - the entire jdk http client is build around CompletableFuture, for a reason.

And your question is not vs ExecutorService, but should really be vs Future. An ExecutorService can still be passed to methods that CompletableFuture provides. For example read this Q&A for what various methods do and act like.

Eugene
  • 117,005
  • 15
  • 201
  • 306
1

The main advantage of the CompletableFuture (at least for me) is that it allows to build a complex asynchronous processes within a higher probability to get it right from the first time and still be able to understand the logic after some time.

Of course the most of it can be implemented using ExecutorService, which will require to subclass it, override some methods, re-submit the task... Most of it is covered by CompletableFuture out of the box. Moreover, with every jdk update the best practices get integrated into the CompletableFuture class.

Thus, the practical reason to use CompletableFuture is the simplicity (well, you still need to understand how to use it).

For example :

CompletableFuture.supplyAsync(...)
    .completeOnTimeout("foo" , 1, TimeUnit.SECONDS);

Is not that simple with ExecutorService to implement.

kofemann
  • 4,217
  • 1
  • 34
  • 39
  • Just the fact that you can chain futures per method-call and complete futures, which is why there is "Completable" in `CompletableFuture`, are big differences. I think saying that the practical reason is just simplicity is too simplistic but I'm not saying you are wrong. – akuzminykh Jul 10 '21 at 21:52
  • Simplicity is quite important. Look at the guava, for example. Most of the methods provide a very basic functionality, but many of those easy to get wrong. At the end, you save on the coding and debugging time. – kofemann Jul 10 '21 at 21:58
  • I will somehow second @akuzminykh, there is a reason that they named it `Completable` vs the already existing `Future`, before that. `Future` is blocking. wanna chain something to a result? block. `ListebableFuture` from guava was an attempt to take on that. – Eugene Jul 11 '21 at 00:11