我有许多临时文件,我打电话给deleteOnExit()
。
我还有一个runnable,我在调用addShutdownHook()
时注册了System.exit
。
当我的关机挂钩运行时,是否可以保证临时文件仍然可用?
答案 0 :(得分:-1)
当我们查看底层实现时,两者都在处理Shutdown-Hook。
当我们处理addShutdownHook(ApplicationShutdownHooks)时,我们在代码中有一段类似于下面的代码。
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
<<---Do the Implementations here--->>
}
});
在Java源代码内部内部,ApplicationShutdownHooks的实现如下,并从运行时类中调用,如此链接https://maps.googleapis.com/maps/api/geocode/json?key=YOUR_VERY_OWN_KEY&latlng=-7.79611,110.36194&result_type=administrative_area_level_3&language=en
中所述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();
}
}
);
当我们处理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://www.docjar.com/html/api/java/lang/Runtime.java.html http://hg.openjdk.java.net/icedtea/jdk7/jdk/file/10672183380a/src/share/classes/java/io/DeleteOnExitHook.java
如果Shutdown Hook运行正常,我们将从系统中清除所有文件。但是,不能保证Shutdown Hooks每次都能正常运行。还有一些罕见的场景,您可以参考以下链接:
ApplicationShutdownHooks:http://hg.openjdk.java.net/icedtea/jdk7/jdk/file/10672183380a/src/share/classes/java/io/File.java (java.lang.Thread)
deleteOnExit: https://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html#addShutdownHook
更具体地说,我们应该使用ApplicationShutdownHooks而不是deleteOnExit(),因为deleteOnExit()使用了大量的内存,直到JVM终止,这些内存才被释放。
注意:此外,由于deleteOnExit()适用于File实例而不是Path,因此我们还需要转换Path 通过调用以下方法将其添加到文件:
Path path = FileSystems.getDefault.getPath(".");
File asFile = path.toFile();
asFile.deleteOnExit();