Platform.exit()在JavaFX中的无限循环内无效

时间:2019-08-26 00:00:33

标签: java javafx lambda exit

EDIT :我最初认为此问题是由ifPresentOrElse语句引起的,但是我现在知道并非如此而无限的while循环是这种行为的罪魁祸首,并且已将问题重命名(请参阅评论和选择的答案)。

存在一个现有的问题here,与此问题具有相似的行为,但是我认为解决方案足够不同,因此不能被视为重复项。

原始问题:

假设我有一个JavaFX应用程序,其启动方法(在应用程序线程中)包含以下代码:

while(true) {
        new TextInputDialog().showAndWait()
       .ifPresentOrElse(System.out::println, 
                        Platform::exit);
}

其行为应是,如果按下 TextInputDialog OK 按钮(显示结果),则应打印对话框中输入的文本。如果按下 CANCEL 按钮,将调用Platform::exit语句,并且JavaFX应用程序将退出。

前一种情况按预期工作,但后一种情况不起作用。如果按下 CANCEL 按钮,该应用程序将保持活动状态,并再次打开该对话框,就像按下 OK 按钮一样,但是不会打印任何文本,这意味着必须到达Platform::exit语句,而不是System.out::println语句。为了调试此问题,我将原始代码调整为以下代码:

while(true) {
    new TextInputDialog().showAndWait()
   .ifPresentOrElse(System.out::println, 
                   () -> System.out.println("The latter statement has been reached"));
}

运行此代码并按 CANCEL 按钮时,“已到达后面的语句” 会显示在屏幕上,证明Platform::exit可以通过原始代码访问,但未按预期关闭应用程序。

有趣的是,如果我再次将原始代码编辑为以下内容:

while(true) {
    new TextInputDialog().showAndWait()
   .ifPresentOrElse(System.out::println, 
                    () -> System.exit(0));
}

...程序按预期退出。

我以前从未遇到过这样的行为,而我对发生的事情确实感到茫然。任何见识将不胜感激。

1 个答案:

答案 0 :(得分:5)

阅读Platform.exit()的文档:

  

导致JavaFX应用程序终止。如果在调用Application start方法之后调用此方法,则JavaFX启动程序将调用Application stop方法并终止JavaFX应用程序线程。然后启动器线程将关闭。如果没有其他非守护程序线程在运行,则Java VM将退出。如果从Preloader或Application init方法调用此方法,则可能不会调用Application stop方法。

     

可以从任何线程调用此方法。

可以看出,调用该方法不会杀死线程,因此运行您的while(true)循环的线程将继续运行,并防止程序结束。

您需要更改代码,以便while循环也结束,例如像这样的东西:

AtomicBoolean keepRunning = new AtomicBoolean(true);
while (keepRunning.get()) {
    new TextInputDialog().showAndWait()
        .ifPresentOrElse(System.out::println, 
                         () -> keepRunning.set(false));
}
Platform.exit();