我正在尝试添加对信号的支持(尤其是Ctrl + C)。
我的工具是用Java编写的,当我捕获Ctrl+C时,我想执行清理。
我的主文件是应用程序,代码如下:

if (ArgDefinitions.getInstance().hasOption(ArgNames.EXECUTE)) {
    performShutdownHooks();
    preformRun();
}
应用程序解析用户的选项并运行适当的方法。因此,当用户使用execute选项并单击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()注释掉,它可以正常工作(不会抛出任何异常)。
这使我相信,由于某种原因,即使我没有按performShutdownHooks,方法Ctrl+C仍在运行。
为了解决这个问题,我需要添加一些东西到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的原因。问题是,我不知道如何解决。我从文档中读到:

所以我想,当插件关闭时,它会调用ShutdownHooks(如果我输入错了,请纠正我)。问题是我不了解如何在这两种可能性之间进行区分。我只想捕获信号并执行清理,但是如果其中一台VM关闭,我不想这样做。关于如何处理此问题的任何想法?

最佳答案

关闭 Hook 的常见问题之一是没有确定的关闭顺序。在您的情况下,我假设Schedule框架可能已经具有一个单独的关闭钩子(Hook),该钩子(Hook)已经执行了清除(停止任务)。

与关闭 Hook 相关的javadoc在某种程度上解释了您不能依赖other resources的存在,因为它们可能已经关闭了。

现在,当您尝试在关机 Hook 中执行此操作时,您可能会收到上述错误,具体取决于关机 Hook 的执行顺序。

所有这些都不是您真正想要的,但是我想您可能根本没有问题。我宁愿讨论以下内容

  • 首先要具有关闭钩子(Hook)的原因是什么?
  • 为什么(感觉)您需要自己停止正在运行的作业?

  • 您可能需要添加在清理问题时运行的代码。根据我得到的信息,您可能想要关闭已经关闭的设备。

    如果您仍然想进行Singal拦截,则实际上有一种方法,但我不建议您使用。根据此链接https://www.javaspecialists.eu/archive/Issue043.html,您可以使用sun.misc。*包的Signal类。

    sun.misc软件包仅包含非官方的API,可以随时将其删除而无需另行通知。似乎没有官方的API支持您的用例(至少据我所知)。

    09-09 20:47