有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java使用JavaFX应用程序。Shutdownhook上的stop()方法

所以我用shutdownhook来清理,因为shutdownhooks线程并不总是能执行,我应该把这段代码推到JavaFX应用程序线程(方法stop())上吗?每次我关闭应用程序时,它都会执行?代码运行成本不高,基本上只要关闭socket(如果未关闭)和杀死进程(如果未杀死)

使用应用程序是一种良好的做法。停止()清理关闭挂钩

引用文件:

This method is called when the application should stop, and provides a convenient place to prepare for application exit and destroy resources. The implementation of this method provided by the Application class does nothing.

NOTE: This method is called on the JavaFX Application Thread.

这个方法只是为了清理UI的资源吗?到目前为止,我完全不认为有理由在stop()上使用shutdownhook


共 (1) 个答案

  1. # 1 楼答案

    只有通过Platform.exit()退出应用程序时才会调用stop()(如果Platform.implicitExit为true,则最后一个窗口关闭时)。除了退出JavaFX应用程序的常用方式外,如果调用System.exit(),或者运行JVM的本机进程被中断(例如,在类似*nix的操作系统上使用ctrl-C),则会执行关闭挂钩

    请注意,在调用Application.launch()之前,在主线程中注册关闭挂钩似乎很重要

    stop()在FX应用程序线程上执行,因此可以安全地访问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 -9 idkill -SIGKILL id从命令行退出)既不执行stop()方法也不执行shutdown钩子