【发布时间】:2015-01-26 12:19:08
【问题描述】:
更新: 现在,为了弄清楚,情况是:有一个项目只通过调用A类中的main()函数来启动,并且在main()中添加了一个关闭钩子。 A 启动了许多其他工作线程,并且它们一直运行直到 ShutdownHook 被执行。 我的问题是如何让关闭钩子被执行?我们曾经使用 kill -9 PID 来杀死进程。而且我不确定是否会直接使用 kill 执行关闭挂钩。 我搜索了很多,大多数人说用 kill -9 正确关闭会被忽略吗?但是我的同事说我们一直在使用这种方式来停止服务......我现在完全糊涂了。
public class A {
//...omitted unrelevant
public static void main(String[] args) {
final A ctrl = new A(configName, routerId);
ctrl.startup();
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
if (logger.isWarnEnabled()) {
logger.warn("Kill signal received, starting shutdown...");
}
ctrl.shutdown(); //calling the real shutdown
if (logger.isWarnEnabled()) {
logger.warn("Shutdown done, going down.");
}
Set<Thread> threadSet=Thread.getAllStackTraces().keySet();
String currentThreadName = Thread.currentThread().getName();
for (Thread thread : threadSet) {
if (logger.isWarnEnabled()) {
logger.warn("Killing : " + thread.getName() + " " + thread.getClass().getName());
}
if (!thread.getName().equals(currentThreadName)) {
thread.stop();
}
}
System.exit(0);
}
}
}
// ...
public void shutdown() {
if (logger.isDebugEnabled()) {
logger.debug("requesting shutdown");
}
for (Worker w : worker) {
w.requestShutdown();
}
for (Thread t : workerThreads) {
try {
t.join();
} catch (InterruptedException e) {
}
}
if (logger.isDebugEnabled()) {
logger.debug("shutdown finished");
}
}}
【问题讨论】:
-
kill -9是唯一一个不能被进程拦截的 Unix 信号,因此不会触发任何关闭挂钩。从描述中不清楚你在问什么,也许如果你发布你的代码,你的问题会变得更清楚。 -
我已经更新了我的问题。
-
被
SIGKILL杀死的进程(这是kill -9所做的)将没有任何机会运行任何关闭活动。信号无法被捕获,进程将被简单终止。如果您需要“更柔和”的终止信号,请使用专用的终止信号(SIGINT或SIGTERM)。 -
@kiheru 好的,那你知道如何让它执行正确的关机而不更改原始代码吗?
-
根据docs,'如果虚拟机中止,则不能保证是否会运行任何关闭挂钩。'
标签: java tomcat process pid shutdown