简体   繁体   English

java ExecutorService.awaitTermination() 是否阻塞主线程并等待?

[英]Does java ExecutorService.awaitTermination() block the main thread and wait?

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("-----------");我预计,因为 Runnable 应该休眠 1s 然后结束,然后执行程序等待它的终止和关闭,最后是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.似乎 ExecutorService.awaitXXX 和 shutdown() 不会阻塞主线程。 The System.out.println("-----------"); System.out.println("-----------"); was the first code line to print, and then the Runnable code.是要打印的第一行代码,然后是 Runnable 代码。

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?如果是,那么我的问题是:如果 awaitXXXX 方法没有阻塞主线程,那么主线程如何知道ExecutorService何时完成?

Seems the ExecutorService.awaitXXX and shutdown() doesn't block the main thread似乎 ExecutorService.awaitXXX 和 shutdown() 不会阻塞主线程

Method awaitTermination() does block the calling thread, but you've specified the timeout of 0 seconds.方法awaitTermination()确实会阻塞调用线程,但您已将超时时间指定为0秒。 Quote from the javadoc :引用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.如果您期望awaitTermination()会中断提交的任务,那么您的期望是错误的,它不会那样做。 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返回:如果此执行程序终止,则返回 true;如果在终止前超时,则返回 false

Method shutdown() also will not interrupt any tasks that are previously submitted:方法shutdown()不会中断之前提交的任何任务:

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() .如果您想尝试中断提交的任务,请使用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.注意:使用shutdown()是首选方法。

From the Javadocs of ExecutorService#awaitTermination :来自ExecutorService#awaitTermination的 Javadocs

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() .这意味着awaitTermination只会在关闭请求之后工作,因此您需要在awaitTermination() shutdown() ) 。

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.此外,正如@Alexander Ivanchenko 的另一个回答所提到的,将超时设置为 0L 将不会等待任何内容,并且awaitTermination指示线程是否通过返回值及时终止。 The InterruptedException is thrown if your main thread is interrupted by another thread.如果您的主线程被另一个线程InterruptedException

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM