在 Java 中捕获 Ctrl+C
是否可以在 java 命令行应用程序中捕获 Ctrl+C 信号?我想在终止程序之前清理一些资源。
Is it possible to catch the Ctrl+C signal in a java command-line application? I'd like to clean up some resources before terminating the program.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以附加 VM 的关闭挂钩,每当 VM 关闭时都会运行该钩子:
不过,您作为关闭挂钩传递的线程必须遵循几条规则,因此请仔细阅读链接的文档以避免出现任何问题。这包括确保线程安全、线程的快速终止等。
此外,正如评论者 Jesper 指出的那样,关闭挂钩保证在 VM 正常关闭时运行,但如果 VM 进程被强制终止,则它们不会运行。如果本机代码出错或者强行终止进程(
kill -9
、taskkill /f
),则可能会发生这种情况。但在这些情况下,无论如何,所有的赌注都会被取消,所以我不会在这上面浪费太多的想法。
You can attach a shutdown hook to the VM which gets run whenever the VM shuts down:
The thread you pass as shutdown hook has to follow several rules, though, so read the linked documentation carefully to avoid any problems. This includes ensuring thread-safety, quick termination of the thread, etc.
Also, as commenter Jesper points out, shutdown hooks are guaranteed to run on normal shutdown of the VM but if the VM process is terminated forcibly they don't. This can happen if native code screws up or if you forcibly kill the process (
kill -9
,taskkill /f
).But in those scenarios all bets are off anyway, so I wouldn't waste too much thought on it.
只是为了快速控制台测试目的......
Just for quick console testing purposes...
最上面的答案建议使用关闭挂钩。关闭钩子带来的麻烦远远超过其价值。它们以不确定的顺序运行,并且您所依赖的库可能会添加自己的关闭挂钩,这可能意味着您自己的关闭挂钩所依赖的某些内容可能会在您的关闭挂钩运行之前被取消初始化。避免让自己头痛,并使用信号处理程序:
Signal
目前是sun.misc.Signal
,这意味着它将被弃用 - 但它被替换为当前名为 jdk.internal.misc.Signal,因此在 Java 团队弄清楚如何以非内部方式公开公开信号处理程序之前,请注意此调用可能会消失。但目前(从 JDK 11 开始),sun.misc.Signal 仍然存在。The top answer suggests using a shutdown hook. Shutdown hooks are far more trouble than they are worth. They run in an indeterminate order, and libraries you depend upon may add their own shutdown hooks, which may mean that something your own shutdown hook depends upon may be de-initialized before your shutdown hook runs. Save yourself the headache, and use a signal handler:
Signal
is currentlysun.misc.Signal
, which means it will be deprecated -- but what it's being replaced with is currently namedjdk.internal.misc.Signal
, so until the Java team figure out how to publicly expose signal handlers in a non-internal way, beware that this call may go away. For now though (as of JDK 11),sun.misc.Signal
still exists.