Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
889 views
in Technique[技术] by (71.8m points)

java - What is the recommended way to wait till the Completable future threads finish

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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:

  • it prevents to reuse the executor as it requires its shutdown;
  • it requires you to use that executor for all operations – it will not work with CompletableFutures that are managed in another way;
  • it does not clearly shows your intent, which is to wait for all futures to complete;
  • it is more complex to implement;
  • it does not handle exceptional completion – no exception will be thrown by awaitTermination() if one of the tasks failed.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...