JavaFX任务线程没有终止

时间:2014-03-26 09:52:50

标签: multithreading javafx task

我正在编写一个JavaFX应用程序,我的对象扩展了Task,以提供远离JavaFX GUI线程的并发性。

我的主要课程如下:

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";      
}
}

我遇到的问题是,一旦任务完成,就好像启动任务的线程继续运行一样。因此,当我按下&#34; X&#34;退出JavaFX应用程序时在右上角,JVM继续运行,我的应用程序不会终止。如果你看看我的主类,我已经放入了System.exit(),这似乎可以解决问题,虽然我知道这不是正确的方法。

在终止我的子线程方面,有人可以建议我需要做什么,以及这样做的可接受方式是什么?例如,检查它们是否完整然后终止。

由于

2 个答案:

答案 0 :(得分:4)

Executors.newFixedThreadPool() ExecutorService表示:

  

池中的线程将一直存在,直到明确关闭为止。

同时检查threadPool.shutdown()的{​​{3}},他们会注意始终关闭游泳池。

您可能必须确保在应用程序的适当位置调用{{1}}。

答案 1 :(得分:3)

Nikos提供的方法(调用关机)很好而且很直接。

另一种方法是为线程创建定义自己的线程工厂。在您的线程工厂中,创建线程守护程序线程。当所有非守护程序线程都已完成时,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的一些地方使用。