Pie*_*rre 73 java command-line control-c
是否有可能在java命令行应用程序中捕获Ctrl+ C信号?我想在终止程序之前清理一些资源.
Joe*_*oey 83
您可以将关闭挂钩附加到VM,该VM在VM关闭时运行:
Java虚拟机关闭以响应两种事件:
当最后一个非守护程序线程退出或调用退出(等效,System.exit)方法时,程序正常退出,或者
虚拟机将响应用户中断(例如键入Ctrl+ C)或系统范围的事件(例如用户注销或系统关闭)而终止.
但是,作为shutdown hook传递的线程必须遵循几条规则,因此请仔细阅读链接文档以避免任何问题.这包括确保线程安全,快速终止线程等.
此外,正如评论者Jesper指出的那样,关闭挂钩保证在VM正常关闭时运行,但如果VM进程被强制终止则不会.如果本机代码搞砸了或强行终止进程(kill -9
,taskkill /f
),就会发生这种情况.
但在这些情况下,所有赌注都是关闭的,所以我不会浪费太多的想法.
bko*_*mac 25
仅用于快速控制台测试......
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
try {
Thread.sleep(200);
System.out.println("Shutting down ...");
//some cleaning up code...
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
e.printStackTrace();
}
}
});
Run Code Online (Sandbox Code Playgroud)
Luk*_*son 15
最上面的答案建议使用关闭挂钩。关闭钩子带来的麻烦远远超过其价值。它们以不确定的顺序运行,并且您所依赖的库可能会添加自己的关闭挂钩,这可能意味着您自己的关闭挂钩所依赖的某些内容可能会在您的关闭挂钩运行之前被取消初始化。省去麻烦,使用信号处理程序:
Signal.handle(new Signal("INT"), // SIGINT
signal -> System.out.println("Interrupted by Ctrl+C"));
Run Code Online (Sandbox Code Playgroud)
Signal
目前是sun.misc.Signal
,这意味着它将被弃用 - 但它被替换的当前名称是jdk.internal.misc.Signal
,因此在 Java 团队弄清楚如何以非内部方式公开公开信号处理程序之前,请注意此调用可能会消失。但目前(从 JDK 11 开始),sun.misc.Signal
仍然存在。