in JDK8 java shutdownhook 优雅关闭 ~ read.

优雅的在Java应用关闭时清理资源

本文基于JDK 1.8.0_45


在实际的Java应用中经常会遇到一些类是需要打开资源,如果资源类在使用完毕时可以使用try-with-resources清理关闭资源,但是如果该资源的生命周期是与应用生命周期相同的时候我们该如何在应用关闭时清理关闭资源呢?

在Java中可以使用Runtime注册一个关闭时的钩子,在这个钩子里的代码就会在应用关闭的时候执行,如下所示:

        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            // do something
        }, "cleanup-thread"));

这种方式注册的线程是一个只初始化了但是没有启动的线程,当JVM开始关闭流程时所有注册的shutdown hook都会被启动并并发执行,在都执行完毕后悔进行可能的退出时的资源清理,然后完全关闭。

另外请注意:

  1. 当关闭流程开始之后只有halt方法可以强制关闭JVM;
  2. 当关闭流程开始之后禁止注册新的shutdown hook或者去除已注册的shutdown hook;
  3. 小心死锁;
  4. 建议不要执行太长时间,这是因为一方面用户在关停应用时不会期望等待太长时间,另一方面可能操作系统不会允许太长时间的关停;
  5. 如果JVM由于一些特殊的原因终止,比如kill -9,JVM不会保证shutdown hook的执行;

如果在注册了一个shutdown hook之后在一些情况下需要将之删除,可以通过以下代码:

        Thread shutdownHook = new Thread(() -> {
            // do something
        }, "cleanup-thread");
        // 注册shutdown hook
        Runtime.getRuntime().addShutdownHook(shutdownHook);

        // 删除shutdown hook
        Runtime.getRuntime().removeShutdownHook(shutdownHook);
分享按钮