Java中的JVM Shutdown Hook

作者: Arvin Chen 分类: Java 来源: Break易站(www.breakyizhan.com)

Shutdown Hooks是一种特殊的结构,允许开发人员插入一段代码,以便在JVM关闭时执行。如果我们需要在VM关闭的情况下进行特殊的清理操作,这就派上用场了。

使用常规构造处理此问题,例如确保在应用程序存在之前调用特殊过程(调用System.exit(0))将不适用于VM因外部原因而关闭的情况(例如kill请求)来自O / S),或者由于资源问题(内存不足)。正如我们将很快看到的那样,关闭钩子可以通过允许我们提供任意代码块来轻松解决这个问题,JVM在关闭时会调用它。

从表面看,使用Shutdown Hooks是直接向前的。我们所要做的就是编写一个扩展java.lang.Thread类的类,并在public void run()方法中提供我们想要在VM关闭时执行的逻辑。然后我们通过调用Runtime.getRuntime()。addShutdownHook(Thread)方法将此类的实例注册为VM的关闭挂钩。如果需要删除以前注册的关闭挂钩,Runtime类也会提供removeShutdownHook(Thread)方法。

例如 :

public class ShutDownHook
{
  public static void main(String[] args)
  {

    Runtime.getRuntime().addShutdownHook(new Thread()
    {
      public void run()
      {
        System.out.println("Shutdown Hook is running !");
      }
    });
    System.out.println("Application Terminating ...");
  }
}

当我们运行上面的代码时,您将看到JVM在完成main方法的执行时调用了shutdown钩子。

输出:

Application Terminating ...
Shutdown Hook is running !

简单吧?是的。

虽然编写一个关闭钩子非常简单,但是需要知道关闭钩子后面的内部才能正确使用它们。因此,在本文中,我们将探讨关闭钩子设计背后的一些“陷阱”。

1.在某些情况下可能无法执行关机挂钩!
首先要记住的是,无法保证关闭挂钩始终会运行。如果JVM由于某些内部错误而崩溃,那么它可能会在没有机会执行单个指令的情况下崩溃。此外,如果O / S给出SIGKILL(http://en.wikipedia.org/wiki/SIGKILL)信号(Unix / Linux中的kill -9)或TerminateProcess(Windows),则应用程序需要立即终止甚至等待任何清理活动。除了上述内容之外,还可以通过调用Runime.halt()方法来终止JVM而不允许关闭挂钩运行。

当应用程序正常终止时(当所有线程完成或调用System.exit(0)时),将调用关闭挂钩。此外,当JVM由于外部原因(例如用户请求终止(Ctrl + C)),由O / S(正常kill命令,不带-9)或操作系统关闭时发出SIGTERM而关闭时。

2.一旦启动,可在完成前强行停止关机钩。
这实际上是前面解释过的案例的一个特例。虽然钩子开始执行,但在操作系统关闭的情况下,可以在它完成之前终止。在这种情况下,一旦给出SIGTERM,O / S就等待进程终止指定的时间。如果进程未在此时间限制内终止,则O / S通过发出SIGTERM(或Windows中的对应方)强制终止进程。因此,当关闭钩子执行到一半时,可能会发生这种情况。

因此,建议确保快速写入关机挂钩,确保它们快速完成,并且不会导致死锁等情况。此外,JavaDoc [1]特别提到不应该执行长计算或在关闭钩子中等待用户I / O操作。

3.我们可以有多个关机挂钩,但不保证执行顺序。
正如您可能已经通过addShutdownHook方法的方法名称(而不是setShutdownHook)正确猜到的那样,您可以注册多个关闭挂钩。但是JVM无法保证这些多个钩子的执行顺序。JVM可以以任意顺序执行关闭挂钩。此外,JVM可以同时执行所有这些挂钩。

4.我们无法在关闭挂钩中注册/取消注册关闭挂钩
一旦JVM启动关闭序列,就不允许添加更多或删除任何现有的关闭挂钩。如果尝试这样做,JVM将抛出IllegalStateException。

5.一旦关闭序列启动,它只能由Runtime.halt()停止。
一旦关闭序列启动,只有Runtime.halt()(强制终止JVM)才能停止执行关闭序列(除了SIGKILL等外部影响)。这意味着在Shutdown Hook中调用System.exit()将不起作用。实际上,如果你在Shutdown Hook中调用System.exit(),VM可能会卡住,我们可能不得不强行终止进程。

6.使用shutdown hooks需要安全权限。
如果我们使用Java安全管理器,则执行添加/删除关闭挂钩的代码需要在运行时具有shutdownHooks权限。如果我们在安全环境中未经许可调用此方法,则会导致SecurityException。

  •   本文标题:Java中的JVM Shutdown Hook - Break易站
    转载请保留页面地址:https://www.breakyizhan.com/java/4981.html
    扫描二维码添加微信 
  • ,领取淘宝优惠券,淘宝购物更优惠。现在添加微信,还可以领取机械键盘优惠券!添加微信后,分享淘宝选中的机械键盘给淘宝机器人即可领取!
    支持我们,就用微信淘宝!

    发表笔记

    电子邮件地址不会被公开。 必填项已用*标注

    更多阅读