当前位置: 首页 > 面试题库 >

在Shutdownhook上使用JavaFX Application.stop()方法

方恺
2023-03-14
问题内容

因此,我正在使用shutdownhook进行清理,请放心,因为它并不总是保证shutdownhooks线程能够执行,我是否应该将此代码推送到每次关闭我的应用程序时都会执行的JavaFX
Application Thread(方法stop())上?如果不关闭代码,运行基本上关闭的套接字,如果不杀死它,则杀死进程并不昂贵。

使用Application.stop()通过ShutdownHook进行清理是否是一种好习惯?

来自doc的引用:

当应用程序停止时将调用此方法,该方法提供了方便的位置来为应用程序退出和破坏资源做准备。Application类提供的此方法的实现不执行任何操作。

注意:在JavaFX Application Thread上调用此方法。

此方法仅用于清理UI资源吗?到目前为止,我完全看不到在stop()上使用shutdownhook的原因。


问题答案:

stop()仅当您通过退出应用程序时Platform.exit()(或如果最后一个窗口Platform.implicitExit为true
则关闭了该窗口时),
才会调用。System.exit()除了退出JavaFX应用程序的常规方法外,如果调用shutdown挂钩,或者如果运行JVM的本机进程被中断(例如,在*
nix之类的OS上的ctrl-C),则将执行关闭挂钩。

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

stop()是在FX Application
Thread上执行的,因此可以安全地访问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()方法,也不会执行关闭钩子。



 类似资料:
  • 问题内容: 我有一个带有两个类方法的类(使用函数),用于获取和设置本质上是静态变量的东西。我试图将函数与这些函数一起使用,但会导致错误。我能够在解释器中使用以下代码重现该错误: 我可以演示类方法,但是它们不能用作属性: 是否可以将property()函数与类方法修饰的函数一起使用? 问题答案: 属性是在类上创建的,但会影响实例。因此,如果要使用属性,请在元类上创建该属性。 但是由于无论如何都使用元

  • 问题内容: 有人可以给MWE 直接在方法上使用注释的方法吗? 我已经看到了无数的关于在类定义中使用它的示例-但还没有方法的示例。 引用文档: 这种添加到一个类定义或 一个方法 @Target(value = {TYPE, METHOD }) 因此,我认为还有一种可能性和预期的用途-但不幸的是,我无法弄清楚。 问题答案: 这里的DataSource类具有属性url,用户名,密码,driverClas

  • 上面的代码在桌面JVM上工作,发送一个帖子请求,在服务器端成功解析,响应200,但是在Android系统上,请求方法保持GET(是的,我检查了它是假的),并导致404异常。官方文档表示,将doOutput设置为true会触发将请求方法设置为POST,但情况似乎并非如此。

  • 问题内容: 我正在尝试使用这段代码在laravel雄辩的查询生成器的withCount方法上执行where子句。 这段代码给了我这个错误。 SQLSTATE[42S22]: Column not found: 1054 Unknown column ‘upvotes_count’ in ‘where clause’ (SQL: select , (select count() from upvot

  • 我想有一种简单的方法来构建测试数据,并发现生成器模式非常适合这里描述的情况。然而,为了减少组件测试中的样板代码,甚至更多,我发现来自龙目岛项目的@Builder是一个很好的候选人。然而,我找不到任何关于如何在方法上使用它的留档或在线示例。我想在某种工厂方法上使用,因为我不能对实现进行任何更改。 有人能举例说明如何在方法上实际使用?

  • 本文向大家介绍在Linux上安装和使用Docker的方法,包括了在Linux上安装和使用Docker的方法的使用技巧和注意事项,需要的朋友参考一下 容器现在风靡于 IT 界 —— 这很好理解。容器是轻量级的,包含应用运行所需所有东西(代码、库、运行时环境、系统设置,以及依赖关系)的独立的包。每个容器都部署于它自己的 CPU、内存、块 I/O,以及网络资源上,所有这些都不依赖于某个内核和操作系统。这