新线程,阶段关闭后应用程序仍在运行 [英] new Thread, application still running after Stage-close

查看:198
本文介绍了新线程,阶段关闭后应用程序仍在运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

So I followed this tutorial: https://www.youtube.com/watch?v=gyyj57O0FVI

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

and I made exactly the same code in 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();
}

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

After I close the Window, application/thread is still running in the system. My guess its because the infinite loop, but shouldnt the thread be terminated with application closing?

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

Second thing is that when I try to set the text for Label I get the error:

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)

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

...yes, I am going to read more about threads, but I would like to know the answer to these questions.

推荐答案

第一部分

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

Part I

A thread, when created, runs independent of other threads. You have a new thread which has an infinite loop, which implies, it will keep running forever, even after the stage has been closed.

通常不建议使用无限循环,因为要打破该循环非常困难.

Normally, using a infinite loop is not advised, because breaking out of it is very difficult.

建议您使用:

  • TimerTask
  • ScheduledExecutorService

然后您可以呼叫其中一个(根据您使用的是什么)

You can then call either one of them (based on whatever you are using)

  • TimerTask.cancel()
  • ScheduledExecutorService.shutdownNow()

舞台关闭时.您可以使用类似:

when your stage is closed. You can use something like :

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

JavaFX API的 (感谢James_D评论的)

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

These do not need to be explicitly canceled as ScheduledService uses daemon threads and AnimationTimer runs on the JavaFX thread.

  • ScheduledService
  • AnimationTimer

问题的第二部分已在论坛中一次又一次地得到回答.

Your second part of the question has been answered time and again in the forum.

您需要使用JavaFX Application线程才能使用场景图元素.

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

由于创建了新线程并尝试更新label(它是一个JavaFX节点),因此它将引发异常.有关更多信息,请访问:

Since you have created a new thread and trying to update label, which is a JavaFX node, it throws the exception. For more information, please visit:

尝试删除形状时出现JavaFX错误

为什么会收到java.lang.IllegalStateException不在FX应用程序线程上"在JavaFX上?

Javafx在使用计时器时不在fx应用程序线程上

这篇关于新线程,阶段关闭后应用程序仍在运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆