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

时间:2016-03-25 06:45:44

标签: java multithreading shutdown threadpoolexecutor

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

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

我这样做是对的吗?

threadPool.shutdown();

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

2 个答案:

答案 0 :(得分:1)

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

    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随着时间的推移单调增加,但不需要命中每个状态。 过渡是:

RUNNING - > SHUTDOWN
在调用shutdown()时,可能隐含在finalize()

(RUNNING或SHUTDOWN) - > STOP
在调用shutdownNow()

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

停止 - >整理
当游泳池为空时

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

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

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

答案 1 :(得分:1)

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

How to wait for completion of multiple tasks in Java?

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

How to forcefully shutdown 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();
   }