注册新的虚拟机来关闭钩子。
java 虚拟机会为了响应以下两类事件而关闭:
关闭钩子 只是一个已初始化但尚未启动的线程。虚拟机开始启用其关闭序列时,它会以某种未指定的顺序启动所有已注册的关闭钩子,并让它们同时运行。运行完所有的钩子后,如果已启用退出终结,那么虚拟机接着会运行所有未调用的终结方法。最后,虚拟机会暂停。注意,关闭序列期间会继续运行守护线程,如果通过调用 exit
方法来发起关闭序列,那么也会继续运行非守护线程。
一旦开始了关闭序列,则只能通过调用 halt
方法来停止这个序列,此方法可强行终止虚拟机。
一旦开始了关闭序列,则不可能注册新的关闭钩子或取消注册先前已注册的钩子。尝试执行这些操作会导致抛出 illegalstateexception
。
关闭钩子可在虚拟机生命周期中的特定时间运行,因此应保护性地对其进行编码。特别是应将关闭钩子编写为线程安全的,并尽可能地避免死锁。关闭钩子还应该不盲目地依靠某些服务,这些服务可能已注册了自己的关闭钩子,所以其本身可能正处于关闭进程中。例如,试图使用其他基于线程的服务(如 awt 事件指派线程)可能导致死锁。
关闭钩子应该快速地完成其工作。当程序调用 exit
时,虚拟机应该迅速地关闭并退出。由于用户注销或系统关闭而终止虚拟机时,底层的操作系统可能只允许在固定的时间内关闭并退出。因此在关闭钩子中尝试进行任何用户交互或执行长时间的计算都是不明智的。
与其他所有线程一样,通过调用线程 threadgroup
对象的 uncaughtexception
方法,可在关闭钩子中处理未捕获的异常。此方法的默认实现是将该异常的堆栈跟踪打印至 system.err
并终止线程;它不会导致虚拟机退出或暂停。
仅在很少的情况下,虚拟机可能会中止,也就是没有完全关闭就停止运行。虚拟机被外部终止时会出现这种现象,比如在 unix 上使用 sigkill 信号或者在 microsoft windows 上调用 terminateprocess。如果由于内部数据结构损坏或试图访问不存在的内存而导致本机方法执行错误,那么可能也会中止虚拟机。如果虚拟机中止,则无法保证是否将运行关闭钩子。
- 参数:
hook
- 一个已初始化但尚未启动的 thread
对象
- 抛出:
illegalargumentexception
- 如果指定的钩子已注册,或者可以确定钩子正在运行或者已运行完毕
illegalstateexception
- 如果虚拟机已经处于关闭进程中
securityexception
- 如果安全管理器存在并且拒绝 runtimepermission
("shutdownhooks")- 从以下版本开始:
- 1.3
- 另请参见:
removeshutdownhook(java.lang.thread)
,
halt(int)
,
exit(int)