Java ExecutorService: awaitTermination of all recursively created tasks

后端 未结 11 2123
太阳男子
太阳男子 2020-11-29 03:27

I use an ExecutorService to execute a task. This task can recursively create other tasks which are submitted to the same ExecutorService and those

11条回答
  •  执念已碎
    2020-11-29 03:59

    The only inelegant solution I could come up with is to directly use a ThreadPoolExecutor and query its getPoolSize() every once in a while. Is there really no better way do do that?

    You have to use shutdown() ,awaitTermination()and shutdownNow() methods in a proper sequence.

    shutdown(): Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted.

    awaitTermination():Blocks until all tasks have completed execution after a shutdown request, or the timeout occurs, or the current thread is interrupted, whichever happens first.

    shutdownNow(): Attempts to stop all actively executing tasks, halts the processing of waiting tasks, and returns a list of the tasks that were awaiting execution.

    Recommended way from oracle documentation page of ExecutorService:

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

    You can replace if condition with while condition in case of long duration in completion of tasks as below:

    Change

    if (!pool.awaitTermination(60, TimeUnit.SECONDS))
    

    To

     while(!pool.awaitTermination(60, TimeUnit.SECONDS)) {
         Thread.sleep(60000);
     }  
    

    You can refer to other alternatives (except join(), which can be used with standalone thread ) in :

    wait until all threads finish their work in java

提交回复
热议问题