【问题标题】:Java deleteOnExit and addShutdownHook - which comes first?Java deleteOnExit 和 addShutdownHook - 哪个先出现?
【发布时间】:2015-05-12 06:56:09
【问题描述】:

我有一些我称之为deleteOnExit() 的临时文件。 我还有一个在addShutdownHook() 注册的可运行文件,以便在调用System.exit 时运行。

是否可以保证在我的关闭挂钩运行时临时文件仍然可用?

【问题讨论】:

标签: java java-io shutdown-hook


【解决方案1】:

当我们查看底层实现时,两者都在处理 Shutdown-Hook。

  1. 当我们处理 addShutdownHook (ApplicationShutdownHooks) 时,我们的代码中有一段类似下面的代码。

    Runtime.getRuntime().addShutdownHook(new Thread() {
          public void run() { 
                <<---Do the Implementations here--->>
          }
        });
    

在 Java 源代码内部,ApplicationShutdownHooks 实现如下,并从运行时类调用,如链接http://www.docjar.com/html/api/java/lang/Runtime.java.html中所述

class ApplicationShutdownHooks {
    /* The set of registered hooks */
    private static IdentityHashMap<Thread, Thread> hooks;
    static {
        try {
            Shutdown.add(1 /* shutdown hook invocation order */,
                false /* not registered if shutdown in progress */,
                new Runnable() {
                    public void run() {
                        runHooks();
                    }
                }
            );
  1. 而当我们处理 File.deleteOnExit() 时,Java 在内部注册如下所示的关闭。

            // DeleteOnExitHook must be the last shutdown hook to be invoked.
            // Application shutdown hooks may add the first file to the
            // delete on exit list and cause the DeleteOnExitHook to be
            // registered during shutdown in progress. So set the
            // registerShutdownInProgress parameter to true.
            sun.misc.SharedSecrets.getJavaLangAccess()
                .registerShutdownHook(2 /* Shutdown hook invocation order */,
                    true /* register even if shutdown in progress */,
                    new Runnable() {
                        public void run() {
                           runHooks();
                        }
                    }
            );
    

    注意:上面注册钩子的代码可以在JavaSourceCode中找到,如下所示:http://hg.openjdk.java.net/icedtea/jdk7/jdk/file/10672183380a/src/share/classes/java/io/DeleteOnExitHook.java http://hg.openjdk.java.net/icedtea/jdk7/jdk/file/10672183380a/src/share/classes/java/io/File.java

如果 Shutdown Hook 运行正常,我们将从系统中清除所有文件。但是,不能保证 Shutdown Hooks 每次都能正常运行。还有一些罕见的场景,您可以参考以下链接:

ApplicationShutdownHooks : https://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html#addShutdownHook (java.lang.Thread)

deleteOnExit: https://docs.oracle.com/javase/7/docs/api/java/io/File.html#deleteOnExit()

更具体地说,我们应该使用 ApplicationShutdownHooks 而不是 deleteOnExit(),因为 deleteOnExit() 使用了大量内存,直到 JVM 终止才会释放。

注意:同样由于 deleteOnExit(),适用于 File 实例而不是 Path,我们还需要转换 Path 通过调用如下方法到文件:

Path path = FileSystems.getDefault.getPath(".");
File asFile = path.toFile();
asFile.deleteOnExit();

【讨论】:

  • 喜欢哪个版本的Java?我看过 OpenJDK 6、7、8 和 11,它们都使用专用的 DeleteOnExitHook 而不是 Runtime.addShutdownHook()。
  • 我的意思是说两者都在内部处理 ShutDownHooks。更新了我的答案以更清晰。
  • 查看底层实现并不构成保证。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-01-05
  • 1970-01-01
  • 2016-03-28
  • 1970-01-01
  • 2013-10-01
  • 2016-04-06
  • 1970-01-01
相关资源
最近更新 更多