java - Stage.setOnCloseRequest() 和 Runtime.addShutdownHook() 有什么区别?

标签 java javafx shutdown shutdown-hook

编写 JavaFX 应用程序时,您可以使用 javafx.stage.Stage 方法为任何 setOnCloseRequest(EventHandler<WindowEvent>) 提供关闭 Hook 。如果您对主 JavaFX 场景执行此操作,它将充当应用程序关闭 Hook ,并可用于安全地保存/释放重要的系统资源等。但是,如果您实现 java.lang.Thread 和使用 Runtime.getRuntime().addShutdownHook(Thread) 方法将其添加为关闭钩子(Hook)。

这些方法之间有什么区别?如果我调用 Platform.exit() ,两者都会起作用吗?如果我调用 System.exit(int) ,两者都会起作用吗?哪一种被认为是最安全的(意思是,更好地确保节省/释放系统资源)方法?除了我应该考虑的方法之外,还有更好的方法吗?

最佳答案

这些是根本不同的事情。

当用户请求关闭该特定阶段(通常通过按窗口中特定于操作系统的“关闭”按钮)时,将执行使用 setOnCloseRequest() 为特定阶段指定的处理程序。它在 FX 应用程序线程上调用,并将在窗口实际关闭之前调用。它的执行并不意味着应用程序正在退出,FX 工具包正在关闭,或者 Java 虚拟机正在退出。这里的处理程序不仅可以假定 FX 工具包仍在运行,还可以修改 UI(因为它位于 FX 应用程序线程上),并且可以通过使用事件来否决关闭窗口的请求。

关闭钩子(Hook)是用户提供的线程,当 Java 虚拟机退出时执行。它是它自己的线程,并作为关闭序列的一部分执行。因此,它不能假设任何其他服务正在运行。来自 API docs :

They should also not rely blindly upon services that may have registered their own shutdown hooks and therefore may themselves in the process of shutting down. Attempts to use other thread-based services such as the AWT event-dispatch thread, for example, may lead to deadlocks.

适用于 AWT 事件调度线程的相同警告也适用于 FX 应用程序线程。

在某些非常特殊的情况下,调用 setOnCloseRequested 处理程序可能表明 JVM 可能很快就会退出。这些情况包括以下所有情况,但我可能遗漏了一些内容:

  1. 处理程序不消耗事件
  2. 该舞台是最后一个开放的舞台
  3. Platform.isImplicitExit() 返回 true
  4. 没有非守护线程正在运行,并且没有任何线程由 Application 实例的 stop() 方法启动

您应该使用哪个完全取决于您想要做什么。如果目标是释放作为 JavaFX 应用程序的一部分启动的资源,这些资源仅在应用程序退出时不再需要,那么我不会使用其中任何一个,而是会覆盖 Application.stop() method .

关于java - Stage.setOnCloseRequest() 和 Runtime.addShutdownHook() 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34417199/

相关文章:

javafx - 更改图表颜色

java - 如何在 JavaFx 或 FXML 中将多个 TilePane 放入组/列表中?

iphone - 在模拟器中关闭 iPhone

windows - EC2 Windows 实例作为开发机器,需要在用户不活动 X 段时间后自动关闭

php - 在 PHP 中,max_execution_time 会影响通过 register_shutdown_function() 调用运行的关闭函数吗?

java - 如何在spark中进行分组

java - 如何检查子类的类型?

java - 将字符串写入文本文件的底行

java - JScrollPane 在行标题上显示图形故障。如何避免这种情况?

java - 当时间单元格超过当前时间时突出显示 JavaFX 中的 TableView 行