我需要在ThreadPoolExecutor完成当前正在执行的任务后完全关闭应用程序。为此,我添加了以下代码:
private void stopAppGracefully()
{
MyApplication.executor.shutdown();
System.exit(0);
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
logger.debug("Called the addShutdownHook()");
//Wait infinitely till executor shut down
while(!MyApplication.executor.isTerminated())
{
continue;
}
int queued = MyApplication.executor.getQueue().size();
int active = MyApplication.executor.getActiveCount();
int notCompleted = queued + active; // approximate
long submitted = MyApplication.executor.getTaskCount();
long completed = MyApplication.executor.getCompletedTaskCount();
long notCompleted2 = submitted - completed; // approximate
logger.debug("App is down..queued...:"+queued);
logger.debug("App is down..active...:"+active);
logger.debug("App is down..queued + active...:"+notCompleted);
logger.debug("App is down..submitted...:"+submitted);
logger.debug("App is down..completed...:"+completed);
logger.debug("App is down..submitted - completed...:"+notCompleted2);
System.gc();
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
Thread[] threadArray = threadSet.toArray(new Thread[threadSet.size()]);
for (int i = 0; i < threadArray.length; i++)
{
logger.debug("Remaining threads: "+ threadArray[i].getName());
}
}
});
}
但我在日志中看到以下信息:
20 Jul 2017 05:03:17 DEBUG | ApplicationDirectoryWatcher | run | 292 - App is down..queued...:0
20 Jul 2017 05:03:17 DEBUG | ApplicationDirectoryWatcher | run | 293 - App is down..active...:0
20 Jul 2017 05:03:17 DEBUG | ApplicationDirectoryWatcher | run | 294 - App is down..queued + active...:0
20 Jul 2017 05:03:17 DEBUG | ApplicationDirectoryWatcher | run | 296 - App is down..submitted...:43
20 Jul 2017 05:03:17 DEBUG | ApplicationDirectoryWatcher | run | 297 - App is down..completed...:43
20 Jul 2017 05:03:17 DEBUG | ApplicationDirectoryWatcher | run | 298 - App is down..submitted - completed...:0
20 Jul 2017 05:03:17 DEBUG | ApplicationDirectoryWatcher | run | 307 - Remaining threads: Finalizer
20 Jul 2017 05:03:17 DEBUG | ApplicationDirectoryWatcher | run | 307 - Remaining threads: Reference Handler
20 Jul 2017 05:03:17 DEBUG | ApplicationDirectoryWatcher | run | 307 - Remaining threads: Thread-3
20 Jul 2017 05:03:17 DEBUG | ApplicationDirectoryWatcher | run | 307 - Remaining threads: Thread-2
20 Jul 2017 05:03:17 DEBUG | ApplicationDirectoryWatcher | run | 307 - Remaining threads: Thread-1
20 Jul 2017 05:03:17 DEBUG | ApplicationDirectoryWatcher | run | 307 - Remaining threads: main
20 Jul 2017 05:03:17 DEBUG | ApplicationDirectoryWatcher | run | 307 - Remaining threads: Signal Dispatcher
仍有七个线程处于活动状态。 如何杀死/阻止这些线程?
我需要停止/杀死属于该应用程序的所有线程。
答案 0 :(得分:2)
ExecutorService.shutdown()
不会立即终止所有正在运行的任务并停止所有线程。它将继续运行当前正在运行的任务。请注意shutdown()
不等待 - 它立即返回,当前任务可能仍在运行。
您可以调用awaitTermination(...)
等待当前正在运行的任务完成,或者shutdownNow()
确实会尝试杀死所有当前正在运行的任务。
要尝试正常关闭ExecutorService
,然后强行关闭// Initiate graceful shutdown
executorService.shutdown();
try {
// Wait one minute for tasks to finish
boolean terminated = executorService.awaitTermination(1L, TimeUnit.MINUTES);
if (!terminated) {
// If not terminated after one minute, shutdown forcefully
executorService.shutdownNow();
}
} catch (InterruptedException e) {
System.err.println("Interrupted while awaiting termination");
}
,如果它在一定时间内没有停止,您可以使用以下内容:
{{1}}
答案 1 :(得分:0)
答案 2 :(得分:0)
从Java文档中我们看到System.exit( int )
方法基本上与手动调用Runtime.getRuntime().exit( int )
方法的工作相同。然后,再看一下addShutdownHook( Thread )
方法的Java文档。引用:
一旦关闭序列开始,就无法注册新的关闭挂钩或取消注册先前注册的挂钩。尝试这些操作中的任何一个都会导致抛出IllegalStateException。
读完这篇文章之后,您可能会遇到同步错误,其中VM在执行System.exit( int )
方法时开始准备暂停阶段,但在实际关闭序列开始之前,addShutdownHook( Thread )
行已执行。结果是它告诉你有线程正在运行,因为它们是有效的,因为VM还没有完全关闭。