I am using CompletableFuture
as shown below in the code. But concerning the way I should wait till all runnables finish, I found two ways and I do not know the difference between them and which one is the best practice? They are as follows:
Code:
this.growSeedFutureList = CompletableFuture.runAsync(new GrowSeedSERun(this.saliencyMat, this.seedXY, this.seedVal), this.growSeedExecutor); this.growSeedFutureList = CompletableFuture.runAsync(new GrowSeedNWRun(this.saliencyMat, this.seedXY, this.seedVal), this.growSeedExecutor); this.growSeedFutureList = CompletableFuture.runAsync(new GrowSeedNERun(this.saliencyMat, this.seedXY, this.seedVal), this.growSeedExecutor); this.growSeedFutureList = CompletableFuture.runAsync(new GrowSeedSWRun(this.saliencyMat, this.seedXY, this.seedVal), this.growSeedExecutor);
First approach to wait till all runnables finish:
this.growSeedExecutor.shutdown(); this.growSeedExecutor.awaitTermination(1, TimeUnit.DAYS);
Second approach to wait till all runnables finish:
CompletableFuture.allOf(this.growSeedFutureList).join();
Please let me know which one is recommended.
CompletableFuture executes these tasks in a thread obtained from the global ForkJoinPool. commonPool(). But we can also create a Thread Pool and pass it to runAsync() and supplyAsync() methods to let them execute their tasks in a thread obtained from our thread pool.
The CompletableFuture. get() method is blocking. It waits until the Future is completed and returns the result after its completion.
Overview. join() is an instance method of the CompletableFuture class. It is used to return the value when the future is complete or throws an unchecked exception if completed exceptionally.
If you really want to wait on all futures, you can simply call join()
on each of them:
growSeedFutureList.forEach(CompletableFuture::join);
The main difference compared to using allOf()
is that this will throw an exception as soon as it reaches a future completed with an exception, whereas the allOf().join()
version will only throw an exception after all futures have completed (exceptionally or not).
Another small difference is that this does not create the intermediary allOf
stage. Such a stage remains useful if you want to do something asynchronously after all futures have completed, instead of just waiting for all of them to complete.
The solution with the executor on the other side has several drawbacks:
CompletableFuture
s that are managed in another way;awaitTermination()
if one of the tasks failed.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With