有没有办法在关闭钩子中添加swing(也就是说,在VM关闭时显示弹出窗口)?
我意识到,如果我尝试创建一个新的JFrame,它会给我一个错误,因为它试图注册一个关闭钩子,因为VM已经关闭而失败。我只是想知道是否实际上有任何解决方法
答案 0 :(得分:14)
你真的不应该这样做。来自the Runtime.addShutdownHook
specification:
Java虚拟机关闭以响应两种事件:
- 程序正常退出,当最后一个非守护程序线程退出或调用
exit
(等效,System.exit
)方法时,或- 虚拟机已终止以响应用户中断,例如键入
^C
或系统范围的事件,例如用户注销或系统关闭。...
关闭挂钩在虚拟机的生命周期中的微妙时间运行,因此应该进行防御性编码。特别是它们应该被编写为线程安全的并且尽可能避免死锁。他们也不应盲目依赖可能已经注册了自己的关机钩子的服务,因此他们自己可能正在关闭。例如,尝试使用其他基于线程的服务(例如AWT事件派发线程)可能会导致死锁。
关机挂钩也应该快速完成工作。当程序调用{{1}}时,期望虚拟机将立即关闭并退出。当虚拟机因用户注销或系统关闭而终止时,底层操作系统可能只允许一段固定的时间来关闭和退出。因此,不建议尝试任何用户交互或在关闭钩子中执行长时间运行的计算。
...
在极少数情况下,虚拟机可能中止,即停止运行而不会干净地关闭。当虚拟机在外部终止时会发生这种情况,例如Unix上的
exit
信号或Microsoft Windows上的SIGKILL
调用。如果本机方法因例如破坏内部数据结构或尝试访问不存在的内存而出错,则虚拟机也可能中止。如果虚拟机中止,则无法保证是否将运行任何关闭挂钩。
此处的特定警告暗示您不执行此操作:
“关机挂钩也应该快速完成工作。”
依赖于可能需要一段时间才能完成其工作的任何,或无限期阻止用户输入的TerminateProcess
对话框,不你应该做什么在你的关机钩子里做。
“尝试使用其他基于线程的服务,例如AWT事件派发线程,可能会导致死锁”
Swing在AWT之上运行,其底层事件派发线程也可能正在关闭。在关闭时尝试使用Swing或AWT不仅会导致死锁,而且可能根本无法工作。
“如果虚拟机中止,则无法保证是否会运行任何关闭挂钩”
无法保证您的用户甚至可能收到您的消息,因为关闭挂钩只能保证在正常退出或终止时运行 - 不停止或中止时。
< / LI> 醇>答案 1 :(得分:4)
关闭挂钩应该尽快执行。这不包括等待用户确认对话框。在任何情况下,您都无法保证Swing事件线程仍在运行。
你不能这样做。
答案 2 :(得分:2)
Swing GUI必须在Event Dispatch Thread上完成,然后
显示容器
致电Shutdown Hook
Simple way,但需要最终用户操作(关闭JDialog
)
答案 3 :(得分:2)
如果有,它将无济于事。
作为JVM关闭的一部分,异步调用关闭挂钩,因此“确认”对话框不会真正确认任何内容,因为您无法停止或撤消关闭过程。等待用户做出决定并不是关闭钩子的意图。交互式程序中的关闭钩子没有意义。 关闭钩子的真实用例是:
用于在JVM关闭时释放资源和其他内务处理
同样重要的是要注意关闭钩子不会一直运行,更多请参阅我的答案:How to shutdown java application correctly from C# one
答案 4 :(得分:-1)
我不确定你的问题,但我认为在JVM关闭时无法运行或显示弹出窗口。它就像你在准备睡觉时试图跑步一样?只是猜测。 :)