我试图在我的ubuntu服务器上运行一个关闭钩子,但是我似乎遇到了多个线程的问题。使用基本的ShutdownHook,当我使用kill <PID>
终止进程时,以下位代码可以正常工作,这意味着关闭行为已激活。
public static void main(String[] args) {
ShutdownHook shutDown = new ShutdownHook();
shutDown.attachShutDownHook();
while(true){}
}
但是这个带有附加线程的相同代码不是
public static void main(String[] args) {
ShutdownHook shutDown = new ShutdownHook();
shutDown.attachShutDownHook();
(new Thread() {
public void run() {
while ( true ) {}
}
}).start();
while(true){}
}
有什么想法吗?
class ShutdownHook {
ShutdownHook() {
}
public void attachShutDownHook() {
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
System.out.println("Shut down hook activating");
}
});
System.out.println("Shut Down Hook Attached.");
}
}
答案 0 :(得分:3)
在仍有非守护程序线程运行时,JVM不会退出。尝试在新主题上调用setDaemon(true)
。
答案 1 :(得分:1)
以我自己的项目为例;
我的核心类产生了一大堆工作线程,工作者运行必须完成的事务。
在我的核心课程中;
Runtime.getRuntime().addShutdownHook(new ShutdownCleanup());
看起来像;
public final class ShutdownCleanup extends Thread() {
public void run() {
log("waiting for worker threads to finish...");
while(WorkerThread.transactionInProgress()) {
Thread.sleep(1000);
}
//close various sockets and resources
}
}
当我在终端中点击Ctrl+C
时,会显示log
消息。因此,关闭挂钩会立即激活,一旦程序准备就绪就不会运行,而是在收到关闭或终止请求后立即运行。
出于这个原因,我相信其他人所说的关于在没有线程存活的情况下永远不会被调用的关闭钩子是错误的。关闭钩子的意义是什么,只有在一切都已经死亡时才会激活?
可能是你正在使用硬杀,例如-9。您是否尝试过使用Ctrl+C
或SIGINT
答案 2 :(得分:0)
java.lang.Runtime.addShutdownHook( Thread )
注册一个新的虚拟机关闭钩子:
Java虚拟机关闭以响应两种 事件:
程序正常退出,当最后一个非守护程序线程退出或时 调用exit(等效,System.exit)方法,或
虚拟机响应用户中断而终止,例如 键入^ C或系统范围的事件,例如用户注销或系统关闭。
您的代码无限期运行,因此永远不会调用关闭挂钩。
[编辑后]
您使用哪个kill
?
kill -9是不可捕获的
kill -2可用于模拟ctrl-c(SIGINT)