使JavaFX应用程序线程等待另一个线程完成

时间:2015-04-22 14:16:48

标签: java multithreading javafx

我在UI线程中调用一个方法。在此方法中,将创建一个新线程。我需要UI线程等到这个新线程完成,因为我需要这个线程的结果来继续UI线程中的方法。但我不想在等待时冻结UI。有没有办法让UI线程在没有忙等待的情况下等待?。

2 个答案:

答案 0 :(得分:8)

你永远不应该让FX应用程序线程等待;它将冻结用户界面并使其无响应,无论是在处理用户操作方面还是在向屏幕呈现任何内容方面。

如果您希望在长时间运行的流程完成后更新UI,请使用javafx.concurrent.Task API。 E.g。

someButton.setOnAction( event -> {

    Task<SomeKindOfResult> task = new Task<SomeKindOfResult>() {
        @Override
        public SomeKindOfResult call() {
            // process long-running computation, data retrieval, etc...

            SomeKindOfResult result = ... ; // result of computation
            return result ;
        }
    };

    task.setOnSucceeded(e -> {
        SomeKindOfResult result = task.getValue();
        // update UI with result
    });

    new Thread(task).start();
});

显然,用任何数据类型替换SomeKindOfResult代表长时间运行过程的结果。

请注意onSucceeded块中的代码:

  1. 必须在任务完成后执行
  2. 可以通过task.getValue()
  3. 访问后台任务的执行结果
  4. 与您启动任务的位置基本相同,因此可以访问所有UI元素等。
  5. 因此,这个解决方案可以做任何你可以做的事情,等待任务完成&#34;但是在此期间不会阻止UI线程。

答案 1 :(得分:1)

只需调用一个方法,在Thread完成时通知GUI。像这样:

class GUI{

   public void buttonPressed(){
      new MyThread().start();
   }

   public void notifyGui(){
      //thread has finished!

      //update the GUI on the Application Thread
      Platform.runLater(updateGuiRunnable)
   }

   class MyThread extends Thread{
      public void run(){
         //long-running task

         notifyGui();
      }
   }
}