2015-04-22 142 views
1

我正在調用我的UI線程內的一個方法。在這個方法裏面創建一個新的線程。我需要UI線程等待,直到這個新線程完成,因爲我需要這個線程的結果繼續在UI線程中的方法。但我不想讓UI在等待時凍結。有沒有辦法讓UI線程等待而不需要等待?使JavaFX應用程序線程等待另一個線程完成

+1

如果UI線程等待,UI將被凍結:這兩個短語的含義完全相同。你爲什麼要UI線程「等待」?你能解釋一下你實際想要達到的目標嗎? –

+0

我正在使用的應用程序沒有設置爲多線程,所以UI線程始終在做所有的工作。有一個類是所有對服務器調用的瓶頸,我需要爲該類添加多線程。然而,我無法訪問調用此瓶頸類的對象。 – Jupiter

+0

對不起,這沒有任何意義。使用我在答案中顯示的方法有什麼不妥? –

回答

1

只要調用線程完成時通知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(); 
     } 
    } 
} 
+0

但請注意,通過此代碼,'notifyGui()'將從後臺線程中調用,因此無法直接更新UI:任何UI更新都必須在FX應用程序線程上進行調度。這樣做,您使用的任何數據將被設置在一個線程中,並從另一個線程訪問,因此您需要(稍微)小心以確保您訪問實時值。假設你想更新UI,使用'javafx.concurrent' API要容易得多。 –

+0

@James_D我知道了,我認爲這與實際問題是分開的。我編輯了我的答案,以包含在應用程序線程上更新UI的基礎知識。 –

+0

是的,很難知道,因爲OP沒有解釋他爲什麼要FX應用程序線程「等待」......問題屬於[此類別](http://meta.stackexchange.com/questions/ 66377 /什麼,是最XY-問題)。 –

7

你不應該讓FX應用程序線程等待;它會凍結用戶界面並使其無響應,無論是在處理用戶操作還是在渲染物理屏幕方面。

如果您要在長時間運行過程完成時更新UI,請使用javafx.concurrent.Task API。例如。

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. 必然執行時,經由task.getValue()
    2. 基本上在與您啓動任務的地點相同的範圍內,因此它可以訪問所有UI元素等。

    因此,此解決方案ion可以做任何你可以通過「等待任務完成」來做的事情,但是在此期間不會阻塞UI線程。

  • +0

    如果我可以在UI元素與調用瓶頸類的範圍相同的類中編寫此代碼,這將確實很理想。不幸的是,這種情況並非如此。我無法將代碼添加到處理對瓶頸類中方法的調用的類中。 – Jupiter

    +0

    但是這段代碼進入了UI類。 –