我想要添加信号支持(尤其是Ctrl+C),我的工具是用Java编写的,当捕获到Ctrl+C
时,我想执行清理操作。我的主文件是Application,以下是代码片段:
if (ArgDefinitions.getInstance().hasOption(ArgNames.EXECUTE)) {
performShutdownHooks();
preformRun();
}
应用程序解析用户的选项并运行适当的方法。因此,当用户使用“执行”选项并点击“Ctrl+C”时,我希望程序能够停止并清理区域。 为了处理信号,我添加了“performShutdownHooks”方法,代码如下:
private void performShutdownHooks() {
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
performCleanup();
}
});
}
这个工具能够做我想要的事情-如果我运行它并在运行时杀死它,它会清理(它在后台运行一个特殊的命令)。 问题出现在我没有停止它的时候。我会得到以下异常:
Exception in thread "Thread-2" java.lang.IllegalStateException: Job manager has been shut down.
at org.eclipse.core.internal.jobs.JobManager.schedule(JobManager.java:1104)
at org.eclipse.core.internal.jobs.InternalJob.schedule(InternalJob.java:427)
at org.eclipse.core.runtime.jobs.Job.schedule(Job.java:436)
at glichautil.CommandExecutor.runCommandInBackground(CommandExecutor.java:134)
at glicha.core.Application.performCleanup(Application.java:869)
at glicha.core.Application.access$0(Application.java:838)
at glicha.core.Application$1.run(Application.java:985)
我认为即使我没有尝试杀死进程,
performShutdownHooks
仍会在最后运行。
也许是其他因素导致它被杀死,但不应该这样,因为如果我注释掉方法调用performShutdownHooks()
,它就能正常工作(没有抛出任何异常)。
这让我相信,由于某种原因,即使我没有按下Ctrl+C
,performShutdownHooks
方法仍然在运行。
是否需要在performShutdownHooks
方法中添加一些内容以解决此问题?或者我错过了与addShutdownHook
有关的内容?
如果这是问题的正确解释,那么我认为,如果我能以某种方式取消它在最后的运行,那么它将解决问题。
还可能会发生一些其他线程在代码中被杀死并且由于某些原因执行了该方法。编辑:我认为我已经理解了为什么会出现这种情况。在进入我的
ShutdownHooks
方法之前,它先打印:Job found still running after platform shutdown.
Jobs should be canceled by the plugin that scheduled them during shutdown: glicha.testmanager.HandleParallelJobs.
我猜这个问题与
ShutdownHooks
有关。问题在于,我不知道如何解决。我从文档中了解到:Java虚拟机响应两种事件而关闭: 1.程序正常退出,即最后一个非守护线程退出或调用退出方法(等效于System.exit); 2.响应用户中断,例如键入Ctrl+C,或系统范围内的事件,例如用户注销或系统关闭。
因此我猜,当插件关闭时,它会调用
ShutdownHooks
(如果我错了,请纠正)。问题在于,我不知道如何区分这两种可能性。我只想捕捉信号并执行清理工作,但如果VM之一关闭,我不想这样做。有什么想法吗?
Glicha
是该工具的名称。performCleanup
停止所有正在运行的作业。Schedule
是一个第三方框架(可能甚至是 Java 内置的)。 - vesii