4

This is the code which is working but I am specifying the wait time explicitly. Is there any way to exit ExecutorService when all the threads have completed their execution.

    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 am giving here wait time but I don't want this because I don't know when the thread will finish execution

Ravindra babu
  • 37,698
  • 11
  • 250
  • 211
Asmita0915
  • 57
  • 1
  • 8

4 Answers4

2
  • use Future<?> f = executor.submit(new Runnable(...));
  • store the futures in a list
  • after the loop, iterate over the futures and call f.get()

This will block until all the tasks have been executed.

You can then call executor.shutdown().

assylias
  • 321,522
  • 82
  • 660
  • 783
2

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 the futures, you can use them to check for exceptions, or if the task completed ok.

matt
  • 10,892
  • 3
  • 22
  • 34
0

The following method shuts down an ExecutorService in two phases, first by 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 unit) Blocks until all tasks have completed execution after a shutdown request, or the timeout occurs, or the current thread is interrupted, whichever happens first.

0

To terminate the ExecutorService when all tasks are finished, just call es.shutdown(). Your own thread will continue the execution, while the task-threads will process all queued tasks.

From Java Doc:

shutdown Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted. Invocation has no additional effect if already shut down. This method does not wait for previously submitted tasks to complete execution. Use awaitTermination to do that.

You need awaitTermination, when you want to block your own thread.

iBiber
  • 172
  • 4