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.
Both ways are equivalent only when the executor (growSeedExecutor) is used solely for the given task. The first way may lead to following: Another tasks need parallelization, and new executor is created for each task. Some developer sees too many executors created, and decide to use single common executor, but failed to delete all executor shutdowns...
So the second way (join()) is more reliable, since is less complex. But each new future should be added to the growSeedFutureList, not assigned to.