Home > Blockchain >  Does java ExecutorService.awaitTermination() block the main thread and wait?
Does java ExecutorService.awaitTermination() block the main thread and wait?

Time:06-27

I've this test code:

    ExecutorService executor = Executors.newFixedThreadPool(3);
    executor.execute(new Runnable() {
      @Override
      public void run() {
        try {
          System.out.println("run begins");
          Thread.sleep(1000);
          System.out.println("run ends");
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    });
    try {
      executor.awaitTermination(0L, TimeUnit.SECONDS);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    executor.shutdown();
    System.out.println("-----------");

I expected that, as the Runnable should sleep 1s and then ends, then executor await its termination and shutdown, finally, System.out.println("-----------"); is executed.

But the real output is:

-----------
run begins
run ends

The execution sequence doesn't make much sense to me. Seems the ExecutorService.awaitXXX and shutdown() doesn't block the main thread. The System.out.println("-----------"); was the first code line to print, and then the Runnable code.

Is this the designed behavior?

If yes, then my question is: if awaitXXXX method doesn't block the main thread, how does the main thread know when ExecutorService is done?

CodePudding user response:

From the Javadocs of ExecutorService#awaitTermination:

Blocks until all tasks have completed execution after a shutdown request

This means that awaitTermination will only work after a shutdown request so you need to call shutdown() before awaitTermination().

Furthermore, as the other answer by @Alexander Ivanchenko mentions, setting a timeout of 0L will not wait for anything and awaitTermination indicates whether the thread terminated in time via a return value. The InterruptedException is thrown if your main thread is interrupted by another thread.

CodePudding user response:

Seems the ExecutorService.awaitXXX and shutdown() doesn't block the main thread

Method awaitTermination() does block the calling thread, but you've specified the timeout of 0 seconds. Quote from the javadoc:

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

In case if you expected that awaitTermination() will interrupt submitted tasks, then your expectation is wrong, it wouldn't do that. This method only allows you to specify the period to wait and reports whether executor is done or not.

Returns: true if this executor terminated and false if the timeout elapsed before termination

Method shutdown() also will not interrupt any tasks that are previously submitted:

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

If you wish to try to interrupt submitted tasks, use 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.

Note: usage of shutdown() is a preferred approach.

  • Related