在ExecutorService中等待完成Runnable任务的有效方法

时间:2013-05-02 06:26:36

标签: java multithreading executorservice

我正在使用ExecutorService执行n个Runnable任务(不可调用)。

我想等待所有任务完成。

我不能使用invokeAll - 因为它适用于收集Callables。

我无法使用shutdown()+awaitTermination,因为awaittermination需要提供超时,但我的任务可能需要数小时才能完成。

我可以使用:

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

但是这个循环总会被触发。

在这种情况下建议什么?

3 个答案:

答案 0 :(得分:4)

ExecutorService.awaitTermination()返回boolean,表示执行程序是否已终止或超时是否已过。你可以在一个循环中调用它:

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");

答案 1 :(得分:2)

您可以使用ExecutorService.awaitTermination(Long.MAX_VALUE, TimeUnit.HOURS);

答案 2 :(得分:1)

对于已知数量的任务,CountDownLatch非常完美,但有些情况下,当您不知道将要执行多少任务时,我会使用Semaphore。例如:

    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();
   }
}