在Shutdownhook上使用JavaFX Application.stop()方法
所以我使用shutdownhook来清理,因为它并不总是保证shutdownhooks线程执行,我应该把这个代码推送到每次关闭我的应用程序时执行的JavaFX应用程序线程(方法stop())吗? 如果没有关闭代码运行它基本上只是关闭套接字并且如果没有被杀死则杀死进程并不昂贵。
使用Application.stop()来清理ShutdownHook是一种好习惯吗?
从文档引用:
当应用程序停止时调用此方法,并为应用程序退出和销毁资源提供方便的准备。 Application类提供的此方法的实现不执行任何操作。
注意:此方法在JavaFX Application Thread上调用。
此方法仅用于清理UI的资源吗? 到目前为止,我根本没有看到使用shutdownhook over stop()的原因。
只有通过Platform.exit()
退出应用程序时才会调用stop()
(如果Platform.implicitExit
为true,则关闭最后一个窗口)。 如果调用System.exit()
,或者运行JVM的本机进程被中断(例如,类似* nix的OS上的ctrl-C),则执行关闭挂钩,以及退出JavaFX应用程序的常用方法。
在FX应用程序线程上执行stop()
,因此访问UI元素是安全的(例如,显示“保存未保存的更改”对话框等)。 关闭挂钩在后台线程中运行,因此无法访问UI元素(事实上FX Toolkit可能很久就会停止在该阶段运行)。
所以选择取决于用例。
为了使这更具体,这是一个快速测试类:
import javafx.application.Application; import javafx.application.Platform; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.layout.HBox; import javafx.stage.Stage; public class ShutdownTest extends Application { @Override public void start(Stage primaryStage) { Button platformExit = new Button("Platform Exit"); platformExit.setOnAction(e -> Platform.exit()); Button systemExit = new Button("System Exit"); systemExit.setOnAction(e -> System.exit(0)); Button hang = new Button("Hang"); hang.setOnAction(e -> {while(true);}); HBox root = new HBox(5, platformExit, systemExit, hang); root.setPadding(new Insets(20)); root.setAlignment(Pos.CENTER); Scene scene = new Scene(root); primaryStage.setScene(scene); primaryStage.show(); } @Override public void stop() { System.out.println("Stop"); } public static void main(String[] args) { Runtime.getRuntime().addShutdownHook(new Thread(() -> System.out.println("Shutdown hook"))); launch(args); } }
我在Mac OS X上测试了这个。
通过“平台退出”按钮退出,关闭窗口,或右键单击Dock并选择“退出”将同时执行stop()
方法和关闭钩子。
通过“系统退出”按钮退出,通过强制进程退出“活动监视器”,或通过命令行中的kill id
终止进程,将仅执行关闭挂钩。 通过按“挂起”按钮挂起应用程序,然后右键单击Dock并选择“强制退出”具有相同的结果。
通过向进程发送SIGKILL退出( kill -SIGKILL id
kill -9 id
或kill -SIGKILL id
)既不执行stop()
方法也不执行shutdown hook。