繁体   English   中英

等待ThreadPoolExecutor在java中完成线程的最佳方法是什么?

[英]what is the best way to wait ThreadPoolExecutor finish thread in java?

我在java中使用ThreadPoolExecutor来执行多线程,并且我必须在线程完成后做一些事情,并且必须等待。

所以我想问一下最好的方法是什么?

我这样做是对的吗?

threadPool.shutdown();

boolean loop = true;
Integer x = threadPool.getPoolSize();
while (threadPool.getPoolSize() != 0) {
}

关闭将启动有序关闭,其中先前提交的任务将被执行,但不会接受任何新任务。

    executor.shutdown();
    System.out.println("All tasks submitted...No new tasks will be admitted");

但是,我强烈建议使用awaitTermination,因为这将允许当前线程阻塞,直到所有任务在关闭请求之后完成执行,或发生超时,或者当前线程被中断,以先发生者为准。

    try {
        executor.awaitTermination(3, TimeUnit.SECONDS);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

编辑:

 The runState provides the main lifecyle control, taking on values:

 *   RUNNING:  Accept new tasks and process queued tasks
 *   SHUTDOWN: Don't accept new tasks, but process queued tasks
 *   STOP:     Don't accept new tasks, don't process queued tasks,
 *             and interrupt in-progress tasks
 *   TIDYING:  All tasks have terminated, workerCount is zero,
 *             the thread transitioning to state TIDYING
 *             will run the terminated() hook method
 *   TERMINATED: terminated() has completed

这些值之间的数字顺序很重要,以允许有序比较。 runState随着时间的推移单调增加,但不需要命中每个状态。 过渡是:

跑步 - >关机
在调用shutdown()时,可能隐含在finalize()中

(RUNNING或SHUTDOWN) - >停止
关于调用shutdownNow()

关机 - >整理
当队列和池都为空时

停止 - >整理
当游泳池空了

整理 - >终止
当terminate()钩子方法完成时。 在awaitTermination()中等待的线程将在状态达到TERMINATED时返回。

检测从SHUTDOWN到TIDYING的转换不如你想要的那么简单,因为在非空状态下队列可能变空,反之亦然在SHUTDOWN状态,但我们只能在看到它为空后看到workerCount时终止是0。

回到你的问题,当你调用getPoolSize()时,它会检查线程池处于TIDYING状态时的状态。 因此,我认为正确的检查应该是针对TERMINATED状态。 虽然,如果您没有实现terminate()方法,结果是相同的。

如果您想优雅地等待,请参阅以下问题中的解决方案:

如何在Java中等待完成多个任务?

如果您没有使用它们中的任何一个( invokeAllCountDownLatch )并提交作业并等待执行程序完成任务,请参阅

如何强制关闭java 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();
   }

暂无
暂无

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

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