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