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

Cyb*_*ent 3 java lambda javafx exit

编辑:我本来以为这个问题是由ifPresentOrElse语句引起的,但是我现在知道情况并非如此,无限的while循环应归咎于这种行为,并重命名了问题(请参阅评论和选择的答案)。

有一个现有的问题,在这里共享一个类似的行为这个问题,但是我认为,解决方案是不同的足够这不应被视为重复。

原始问题:

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

while(true) {
        new TextInputDialog().showAndWait()
       .ifPresentOrElse(System.out::println, 
                        Platform::exit);
}
Run Code Online (Sandbox Code Playgroud)

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

前一种情况按预期工作,而后一种情况则不然。如果按下了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"));
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

...程序按预期退出。

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

And*_*eas 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();
Run Code Online (Sandbox Code Playgroud)