How do I exit the ExecutorService after all threads have completed their execution?
This is the code that works, but I am specifying the timeout explicitly. Is there a way to exit ExecutorService
when all threads have finished executing.
ExecutorService es = Executors.newCachedThreadPool();
{
for(final List<String> list:partitions){
es.execute(new Runnable() {
public void run() {
try{
System.out.println(list);
new CallAPI().make_call(list, access_token);
}catch(Exception e){
System.out.println(e);
}
}
});
Thread.sleep(5000);
}
boolean finshed = es.awaitTermination(15, TimeUnit.MINUTES);
es.shutdown();
boolean finshed = es.awaitTermination(15, TimeUnit.MINUTES);
==> I give the timeout here, but I don't want that because I don't know when the thread will finish executing
source to share
It sounds like you want ExecutorService.invokeAll . All you have to do is convert your collection of lists to a collection of Callables.
List<Callable<String>> tasks = partitions.stream()
.map(list->{
System.out.println(list);
new CallAPI().make_call(list, access_token);
return "finished";
}).collect(Collectors.toList());
List<Future<String>> futures = es.invokeAll(tasks);
es.shutdown();
Then you have futures, you can use them to check for exceptions or if the task is ok.
source to share
The following method shuts down the ExecutorService in two steps, first calling shutdown to reject incoming tasks, and then calling shutdownNow if necessary to cancel any lingering tasks:
void shutdownAndAwaitTermination(ExecutorService pool) {
pool.shutdown(); // Disable new tasks from being submitted
try {
// Wait a while for existing tasks to terminate
if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
pool.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
if (!pool.awaitTermination(60, TimeUnit.SECONDS))
System.err.println("Pool did not terminate");
}
} catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
pool.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
}
boolean awaitTermination (long timeout, TimeUnit) Blocks until all tasks have finished executing after a shutdown request, or timed out, or the current thread is interrupted, whichever comes first.
source to share
To terminate the ExecutorService when all tasks have completed, simply call es.shutdown()
. Your own thread will continue executing, and the thread tasks will process all the tasks in the queue.
From Java Doc:
shutdown Causes an orderly shutdown in which previously assigned tasks are performed but new tasks will not be accepted. The call has no additional effect if it is already off. This method does not wait for previously assigned tasks to complete execution. Use the wait function to do this.
You need it awaitTermination
if you want to block your own thread.
source to share