multithreading - 新线程,应用程序在阶段关闭后仍在运行

标签 multithreading javafx-8

所以我遵循了这个教程:https://www.youtube.com/watch?v=gyyj57O0FVI

我在javafx8中编写了完全相同的代码。

public class CountdownController implements Initializable{

@FXML
private Label labTime;

@Override
public void initialize(URL location, ResourceBundle resources) {

    new Thread(){
        public void run(){
            while(true){
                Calendar calendar = new GregorianCalendar();
                int hour = calendar.get(Calendar.HOUR);
                int minute = calendar.get(Calendar.MINUTE);
                int second = calendar.get(Calendar.SECOND);
                String time = hour + ":" + minute + ":" + second;

                labTime.setText(time);
            }

        }
    }.start();
}

关闭窗口后,应用程序/线程仍在系统中运行。我的猜测是因为无限循环,但是线程不应该随着应用程序关闭而终止吗?

第二件事是,当我尝试设置标签文本时,出现错误:

Exception in thread "Thread-4" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-4
    at com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:204)
    at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:364)
    at javafx.scene.Parent$2.onProposedChange(Parent.java:364)
    at com.sun.javafx.collections.VetoableListDecorator.setAll(VetoableListDecorator.java:113)
    at com.sun.javafx.collections.VetoableListDecorator.setAll(VetoableListDecorator.java:108)
    at com.sun.javafx.scene.control.skin.LabeledSkinBase.updateChildren(LabeledSkinBase.java:575)
    at com.sun.javafx.scene.control.skin.LabeledSkinBase.handleControlPropertyChanged(LabeledSkinBase.java:204)
    at com.sun.javafx.scene.control.skin.LabelSkin.handleControlPropertyChanged(LabelSkin.java:49)
    at com.sun.javafx.scene.control.skin.BehaviorSkinBase.lambda$registerChangeListener$60(BehaviorSkinBase.java:197)
    at com.sun.javafx.scene.control.skin.BehaviorSkinBase$$Lambda$144/1099655841.call(Unknown Source)
    at com.sun.javafx.scene.control.MultiplePropertyChangeListenerHandler$1.changed(MultiplePropertyChangeListenerHandler.java:55)
    at javafx.beans.value.WeakChangeListener.changed(WeakChangeListener.java:89)
    at com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:182)
    at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
    at javafx.beans.property.StringPropertyBase.fireValueChangedEvent(StringPropertyBase.java:103)
    at javafx.beans.property.StringPropertyBase.markInvalid(StringPropertyBase.java:110)
    at javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:143)
    at javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:49)
    at javafx.beans.property.StringProperty.setValue(StringProperty.java:65)
    at javafx.scene.control.Labeled.setText(Labeled.java:146)
    at application.CountdownController$1.run(CountdownController.java:29)

...是的,我将阅读更多有关线程的内容,但我想知道这些问题的答案。

最佳答案

第一部分

线程在创建时独立于其他线程运行。您有一个具有无限循环的新线程,这意味着即使在阶段关闭之后,它将永远运行。

通常情况下,不建议使用无限循环,因为突破它非常困难。

建议您使用:

然后您可以调用其中之一(根据您正在使用的内容)

当你的舞台关闭时。您可以使用类似的东西:

stage.setOnCloseRequest(closeEvent -> {
       timertask.cancel();  
});  

JavaFX API (感谢 James_D 评论)

这些不需要显式取消,因为 ScheduledService 使用守护线程,而 AnimationTimer 在 JavaFX 线程上运行。

第二部分

您问题的第二部分已在论坛中多次得到解答。

You need to be on the JavaFX Application thread to use scene graph elements.

由于您创建了一个新线程并尝试更新 label(这是一个 JavaFX 节点),因此它会引发异常。欲了解更多信息,请访问:

JavaFX error when trying to remove shape

Why am I getting java.lang.IllegalStateException "Not on FX application thread" on JavaFX?

Javafx Not on fx application thread when using timer

关于multithreading - 新线程,应用程序在阶段关闭后仍在运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28627585/

相关文章:

java - 在 JavaFX 中以水平和相反的顺序打印数字并显示在标签上

WPF ObservableCollection 不更新?

multithreading - 如何将 Retrofit 2 与 Realm 和 RxJava 结合起来

java - 调用wait()时发生IllegalMonitorStateException

JavaFX 排序列表 : listen the list changes and the list items updated event

JavaFX - TextFlow 中的下标和上标文本

tableview - JavaFX : bind disable property of a button to ObservableList size

每个选定项目的 JavaFX ComboBox 背景颜色

java - 如何确保一行代码对于每个单独的线程仅运行一次?

multithreading - 如何处理laravel作业的多个线程?