我在java中使用ThreadPoolExecutor来执行多线程,并且我必须在线程完成后做一些事情,并且必须等待。
所以我想问一下最好的方法是什么?
我这样做是对的吗?
threadPool.shutdown();
boolean loop = true;
Integer x = threadPool.getPoolSize();
while (threadPool.getPoolSize() != 0) {
}
答案 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?
如果您没有使用其中任何一个(invokeAll
,CountDownLatch
)并提交作业并等待执行人完成任务,请参阅
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();
}