【问题标题】:Issue running shutdown hook in java在java中运行关闭挂钩问题
【发布时间】:2014-01-29 16:00:58
【问题描述】:

我正在尝试让一个关闭挂钩在 java 中运行。这个钩子的目的是写入一个程序被终止的日志文件。 java 应用程序被编译成 jar 文件并使用批处理文件执行,这意味着应用程序的输出进入 cmd.exe 窗口。当此 cmd 窗口关闭时,我希望应用程序记录它已关闭。

该应用程序旨在无限期地运行并在特定时间执行特定任务。因此,程序在“While true”循环中执行一系列检查。我不明白为什么这个钩子不会记录应用程序正在关闭!

在我们的主要方法中:

final Thread mainThread = Thread.currentThread();
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable()
{
    @Override
    public void run()
    {
        try { mainThread.join(); }
        catch (InterruptedException e) { }
        mission.log("Program Closed.", true);
    }
}
));

所有“任务”都是我的一个自定义类的实例,它进行数据记录。当你调用方法“log”时,它有一个 BufferedWriter 并调用它的 .write()、.newLine() 和 .flush() 方法。

当我杀死批处理窗口时,我似乎无法在我的日志文件中获得“程序关闭”行。我做错了什么?

【问题讨论】:

  • 杀死批处理窗口会杀死进程,它不会优雅地停止它。
  • 那么,有没有办法检测到批处理文件关闭,并在日志中输入呢?你似乎在告诉我这根本不可能。
  • 我认为没有办法检测进程是否从进程中被杀死。

标签: java batch-file logging cmd shutdown-hook


【解决方案1】:

强行杀死应用程序,即不优雅,因此 JVM 不知道应用程序正在退出,因此不会调用关闭挂钩。

不幸的是,没有办法(至少在 Windows 中)提供一种机制来确保始终调用挂钩。它只是可以调用的东西,但不能保证。

【讨论】:

    【解决方案2】:

    关闭窗口会终止进程,因此关闭挂钩将不起作用。

    听起来你宁愿根本不杀死这个进程。您应该考虑使用批处理脚本以外的东西。您可以从 Windows 任务调度程序运行可执行 jar 并让它一直在后台运行 - 除非有人故意杀死 java 或发生错误。在这种情况下,您应该尝试捕获异常并以这种方式记录它们。

    【讨论】:

      【解决方案3】:

      没有办法总是在进程退出之前执行某些操作。例如。如果您将插头从墙上插座中拔出,您的计算机会立即关闭。或者,如果进程被操作系统从调度程序中删除以占用 CPU 时间,它也没有机会。

      但是,如果您删除代码

          try { mainThread.join(); }
          catch (InterruptedException e) { }
      

      那么它至少会在某些情况下执行,例如进程的正常终止。在这里检查主线程没有意义,因为关闭钩子是由于主线程完成工作(它退出了 main() 方法)而执行的,或者主线程将继续运行直到JVM 决定终止(在外部终止的情况下)。

      比较接受的How to gracefully handle the SIGKILL signal in Java 答案,其中包含您正在尝试做的另一个示例。

      【讨论】:

      • 好的,你链接的例子是关于 *nix 和苹果操作系统的。据我所知,Windows 没有相当于“kill -9”的功能。不过,我假设关闭我的批处理文件窗口会向 JVM 发送相同的 kill 命令。 (SIGKILL?)
      • 我不知道,但是您是否尝试过删除 2 行代码并关闭窗口?
      • 是的。然而,它仍然不会触发钩子,这让我认为 Jaffar Ramay 和 Dodd10x 是对的。
      • 好像是这样。值得一试。
      【解决方案4】:

      这里的每个人都是正确的——你不能在你的程序上记录一个强制停止。但是,您可能会考虑使用另一个程序来“监视”您的程序并等待它退出。然后,“观察者”程序可以记录原始程序的终止,然后自行退出。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-11
        • 1970-01-01
        • 1970-01-01
        • 2019-01-03
        • 1970-01-01
        • 2011-07-20
        相关资源
        最近更新 更多