yuris
yuris

Reputation: 1129

Efficient way to wait for completion of Runnable tasks in ExecutorService

I have n-number of Runnable tasks (not Callable) that I am executing with ExecutorService.

I want to wait for all the tasks to complete.

I can't use invokeAll - because it works for collection of Callables.

I can't use shutdown()+awaitTermination, because awaittermination requires to provide a time out, but my tasks can take hours to complete.

I can use:

ExecutorService.shutdown();             
while (!ExecutorService.isTerminated()) {}

But this loop will be always triggered.

What is suggested in such scenario?

Upvotes: 1

Views: 2843

Answers (3)

user3270173
user3270173

Reputation: 31

For known number of tasks the CountDownLatch is just perfect but there are cases, when you don't know how many tasks you will have, in that case I use Semaphore. For Example:

    Semaphore s =new Semaphore(0);
    while(..){
     if (isLastTask){
         taskExecutor.execute(new Task(s));
     } else 
         taskExecutor.execute(new Task());
    }
    s.acquire(1);

class Task implement implements Runnable {
   Semaphore s;

   public Task(){
     this(null);
   }

   public Task (Semaphore s){
     this.s = s;
   }

   public void run(){
       ......
      if ( s != null )
          s.release();
   }
}

Upvotes: 1

Evgeniy Dorofeev
Evgeniy Dorofeev

Reputation: 135992

You can use ExecutorService.awaitTermination(Long.MAX_VALUE, TimeUnit.HOURS);

Upvotes: 2

Jesper
Jesper

Reputation: 206776

ExecutorService.awaitTermination() returns a boolean which indicates if the executor terminated or the timeout has elapsed. You can ofcourse call it in a loop:

ExecutorService executor = ...;

executor.shutdown();
while (!executor.awaitTermination(24L, TimeUnit.HOURS)) {
    System.out.println("Still waiting for the executor to finish");
}

System.out.println("Executor finished");

Upvotes: 4

Related Questions