我已经在这个荒谬的问题上奋斗了几个小时,所以现在我正在寻求帮助。
1班轮:我的关机钩子在完成任务之前显然已经终止了。
我正在运行的代码如下所示:
class Test {
static {
Runtime.getRuntime().addShutdownHook(new Thread(Test::shutdown));
}
// more methods
private static void shutdown() {
Collection<Foo> coll = some.instance.ofHashMap.values();
System.out.println("collSize=" + coll.size());
for (Foo o : coll) {
System.out.println("Calling bar on foo");
o.bar();
}
System.out.println("End of hook");
}
}
但输出是:
collSize=1
如果我使用-server选项运行jvm,我可能会很幸运,并且foo&#34;&#34;呼叫吧打印,但它仍然没有打印&#34;挂钩结束&#34;。
不幸的是,我还没有能够创建一个显示问题的简短可执行示例。我有一个,但它显示一切正常工作,并按预期迭代集合。 上面的代码是我正在处理的一个更大的程序的摘录,但是我的关闭是钩子只是做了上面的事情(得到一个非空的集合并迭代)。
有关可能发生的事情的任何想法?我完全迷失在这里......
注意: - 使用Java 8u45编写,编译和运行代码 - 我用Ctrl + C终止程序,因此,JVM存在代码130
答案 0 :(得分:1)
从the docs(强调我的)你只承诺&#34;尽力而为&#34; for shutdown hooks:
关闭挂钩在虚拟机的生命周期中的微妙时间运行,因此应该进行防御性编码。特别是它们应该被编写为线程安全的并且尽可能避免死锁。他们也不应盲目依赖可能已经注册了自己的关机钩子的服务,因此他们自己可能正在关闭。例如,尝试使用其他基于线程的服务(例如AWT事件派发线程)可能会导致死锁。
关机挂钩也应该快速完成工作。当程序调用exit时,期望虚拟机将立即关闭并退出。当虚拟机因用户注销或系统关闭而终止时,基础操作系统可能只允许一段固定的时间来关闭和退出。因此,不建议尝试任何用户交互或在关闭钩子中执行长时间运行的计算。
所以,基本上如果还有其他地方可以做到,那就去做吧。如果你必须在关机钩子中这样做,那就快点。
答案 1 :(得分:0)
原来:
感谢大家的快速回复和帮助。