当前位置: 首页 > 知识库问答 >
问题:

JavaFX任务线程未终止

慎弘化
2023-03-14

我正在编写一个JavaFX应用程序,我的对象扩展任务提供了JavaFXGUI线程之外的并发性。

我的主要课程是这样的:

public class MainApp extends Application {

@Override
public void start(Stage stage) throws Exception {
    Parent root = FXMLLoader.load(getClass().getResource("Sample.fxml"));        
    Scene scene = new Scene(root);       
    stage.setScene(scene);
    stage.setOnCloseRequest(new EventHandler<WindowEvent>() {
        public void handle(WindowEvent t) {
            //I have put this in to solve the threading problem for now.
            Platform.exit();
            System.exit(0);
        }
    });
    stage.show();
}

public static void main(String[] args) {
    launch(args);
}
}

我的GUI控制器示例如下(略作抽象):

ExecutorService threadPool = Executors.newFixedThreadPool(2);
private void handleStartButtonAction(ActionEvent event) {
        MyTask task = new MyTask();
        threadPool.execute(task);
}

目前,我的任务只是进行睡眠并打印数字1到10:

public class MyTask extends Task<String> {

@Override
protected String call() throws Exception {
    updateProgress(0.1, 10);
    for (int i=0;i<=10;i++) { 
        if (isCancelled()) {
            break;
        }
        Thread.sleep(1000);
        System.out.println(i);
        updateProgress(i, 10);  
    }  
    return "Complete";      
}
}

我遇到的问题是,一旦任务完成,就好像启动任务的线程继续运行一样。因此,当我按下右上角的“X”退出JavaFX应用程序时,JVM继续运行,我的应用程序不会终止。如果你看一下我的主课,我已经把系统放进去了。exit()似乎解决了问题,但我知道这不是正确的方法。

有人能建议我在终止我的子线程方面需要做些什么吗?可以接受的方法是什么?i、 例如,检查它们是否完整,然后终止。

谢谢

共有2个答案

封烨伟
2023-03-14

Nikos提供的方法(调用shutdown)是好的、直截了当的。

另一种方法是为线程创建定义自己的线程工厂。在线程工厂中,使线程成为守护线程。当所有非守护线程完成时,JavaFX程序将停止(这意味着即使您没有显式关闭ExecutorService的线程池,您的程序也将退出)。

ExecutorService threadPool = Executors.newFixedThreadPool(
    2, 
    new ThreadFactory() {
        AtomicInteger a = new AtomicInteger(1);

        public Thread newThread(Runnable r) {
            Thread t = new Thread(r, "mythread-" + a.getAndIncrement());
            t.setDaemon(true);
            return t;
        }
    }
);

守护进程线程并不适用于所有服务,有时显式关闭处理更好。

在JDK中的一些地方使用了守护进程线程工厂方法。

田文景
2023-03-14

Executors.newFixedThreadpool()的Javadocs声明:

池中的线程将一直存在,直到显式关闭。

还要检查ExecutorService的使用示例,他们会注意始终关闭池。

您可能必须确保在应用程序的适当位置调用threadPool.shutdown()

 类似资料:
  • 我今天才开始学习JavaFX,我试图通过制作一个Snake克隆来了解更多,但是我在线程方面遇到了麻烦。我想创建一个线程来更新蛇在屏幕上的位置,但是不能以正常的Runnable线程方式使用它,因为我在线程中使用JavaFX来更新绘制到屏幕上的矩形的位置(我知道你不能这样做,必须使用任务,服务,Platform.run稍后,等等?)我创建线程的类扩展了JavaFX。scene.layout.窗格,我试

  • 问题内容: 我是python和线程的新手。我已经编写了充当网络爬虫的python代码,并在网站中搜索特定的关键字。我的问题是,如何使用线程同时运行类的三个不同实例。当实例之一找到关键字时,所有三个实例都必须关闭并停止爬网。这是一些代码。 如何使用线程让Crawler同时执行三个不同的爬网? 问题答案: 似乎没有一种(简单的)方法可以终止Python中的线程。 这是一个并行运行多个HTTP请求的简单

  • 我是JavaFx/并发的新手,所以我在JavaFX中阅读了并发教程,但是我仍然对JavaFX Gui中后台线程的实现有点困惑。 我试图编写一个与一些串行设备(使用JSSC-2.8)接口的小图形用户界面,并根据这些设备的响应更新图形用户界面。但是,在写入消息和设备响应之间有一个延迟,在任意的时间内使用Thread.sleep()对我来说不是一个可靠的编程方式。因此,我想使用并发包中的等待()和通知(

  • 我一直在学习JavaFX的任务,并使用这些任务通过或任务的方法等与应用程序线程进行通信。但是,我的需要知道用户何时按下 GUI 上的按钮,因为这可能会更改任务的 方法需要返回的值。我该怎么做?我知道如何响应单线程应用程序上的按钮按下事件,但不确定如何以线程安全的方式处理它。 到目前为止,这是我所拥有的,这是实现按钮事件的明智方式吗?

  • 我尝试构建一个GUI应用程序,从相机抓取帧并在Tkinter GUI中显示它们。Tkinter mainloop在主线程中执行,而gui的帧抓取和更新在单独的线程中进行。 下面的代码作为一个视频流被抓取并正确显示在我的gui窗口中。但是,当我通过单击“x”来调用on_close()方法来关闭gui时,gui将关闭,但程序不会完全终止。最后一次CLI输出将为“Mainloop stopped!”,但