如何在关闭钩子中使用swing?

dfuffjeb  于 2021-07-09  发布在  Java
关注(0)|答案(5)|浏览(314)

是否有任何可能的方法将swing添加到关闭挂钩中(即,在vm关闭时显示一个弹出窗口)?
我意识到,如果我尝试创建一个新的jframe,它会给我一个错误,因为它试图注册一个shutdown hook,但是失败了,因为vm已经关闭了。我只是想知道是否真的有办法解决这个问题

6ie5vjzr

6ie5vjzr1#

你真的不该这么做。从 Runtime.addShutdownHook 规范:
java虚拟机将关闭,以响应两种事件:
当最后一个非守护进程线程退出或 exit (相当于, System.exit )方法,或者
虚拟机被终止以响应用户中断,例如输入 ^C ,或系统范围的事件,如用户注销或系统关闭。
...
关闭挂钩在虚拟机生命周期中的一个微妙时刻运行,因此应该进行防御性编码。尤其应该将它们编写为线程安全的,并尽可能避免死锁。他们也不应该盲目地依赖那些可能已经注册了自己的关闭钩子的服务,因此在关闭的过程中他们自己可能会被关闭。例如,尝试使用其他基于线程的服务(如awt事件调度线程)可能会导致死锁。
关闭钩子也应该很快完成它们的工作。当程序调用 exit 我们期望虚拟机能够迅速关闭并退出。当虚拟机由于用户注销或系统关闭而终止时,基础操作系统可能只允许有固定的时间关闭和退出。因此,在关闭挂钩中尝试任何用户交互或执行长时间运行的计算是不可取的。
...
在极少数情况下,虚拟机可能会中止,即在未完全关闭的情况下停止运行。当虚拟机在外部终止时,例如使用 SIGKILL unix或 TerminateProcess 访问microsoft windows。如果本机方法出错(例如,损坏内部数据结构或试图访问不存在的内存),虚拟机也可能会中止。如果虚拟机中止,则无法保证是否会运行任何关闭挂钩。
此处的具体警告建议您不要这样做:
“关闭挂钩也应该很快完成工作。”
依赖任何可能需要一段时间才能完成工作的东西,或者无限期地阻止用户输入,比如 JOptionPane 对话框,而不是您应该在关闭挂钩中执行的操作。
尝试使用其他基于线程的服务,例如awt事件调度线程,可能会导致死锁
swing运行在awt之上,awt的底层事件调度线程也可能正在关闭。在关机时尝试使用swing或awt不仅会导致死锁,而且可能根本不起作用。
“如果虚拟机中止,则无法保证是否会运行任何关闭挂钩”
不能保证您的用户甚至可能得到您的消息,因为shutdown hook只保证在它正常退出或终止时运行,而不是在停止或中止时运行。

ewm0tg9j

ewm0tg9j2#

我不确定你的问题,但我认为在jvm关闭时运行或显示弹出窗口是不可能的。就像你在准备睡觉的时候试着跑步?只是猜测。:)

bxfogqkk

bxfogqkk3#

如果有的话,对你没有帮助。
关闭钩子是作为jvm关闭的一部分异步调用的,因此“确认”对话框不会真正确认任何内容,因为您无法停止或反转关闭过程。等待用户做出决定并不是shutdownhook应该做的那种操作。交互式程序中的关闭挂钩没有意义。关闭挂钩的实际用例是:
用于在jvm关闭时释放资源和其他内务管理
同样重要的是要注意,shutdown hook并不总是运行的,更多信息请参见我的答案:如何从c#one正确关闭java应用程序

2guxujil

2guxujil4#

swing gui必须在事件调度线程上完成,然后
在初始线程上创建jdialog或joptionpane
显示容器
需要 Shutdown Hook 方法简单,但需要最终用户操作(关闭 JDialog )

dxxyhpgq

dxxyhpgq5#

关机挂钩应该尽快执行。这不包括等待用户确认对话框。在任何情况下,都不能保证swing事件线程仍在运行。
你不能这么做。

相关问题