2016-04-14 204 views
0

我有一個JavaFX應用程序,該應用程序運行多個執行大量計算的線程。問題是,經過一段時間的UI完全凍結,但我只更新Platform.runLater()使用Platform.runLater()使用多線程的JavaFX UI凍結()

的UI我開始我的主線程派生的線程的休息方式:

mainThread = new MainThread(mc); 
mainThread.start(); 

在這裏我給線程引用主控制器,它將這個引用傳遞給其餘的線程,以便他們可以將內容打印到TextArea。

主線程產卵一次只有2子線程,但是這兩個子線程使用的ExecutorService用線程的配置數量(100+):

executor = Executors.newFixedThreadPool((Integer.valueOf(mainController.getIndexController().getThreadsField().getText()))); 

for(int i = 0; i < newTasks.size(); i++){ 
    Runnable slaveThread = new SlaveThread(dataLink, url); 
    executor.execute(slaveThread); 
} 

現在線程做很多東西,如下載文件,但我想這應該不會影響用戶界面。他們偶爾從界面讀取,但這不應該是問題。

我認爲通過使用platform.runlater(),UI不能被凍結。

Platform.runLater(() -> { 
    mainController.getIndexController().writeToConsole(result); 
}); 

因爲我沒有任何其他修改UI的代碼,所以這肯定是問題所在。該程序執行許多Platform.runLater() - s,這是否太多? 或多少太多?還有其他一些平滑UI的應用程序,比我的更頻繁地更新界面方式,並且運行得很好。可能是什麼問題?謝謝。

回答

2

從您的問題中確實無法確定,但聽起來好像您只是通過撥打Platform.runLater(...)多次調度許多可運行的FX應用程序線程。 「有多少」是無法回答的,因爲它取決於許多因素,但通常你不應該把它們安排得比他們可以消耗的更頻繁。

通常情況下,您可以通過僅在計劃的先前更新已執行時安排UI的新更新來完成此操作。請參閱Throttling javafx gui updates以瞭解執行此操作的技術。

+0

那麼這意味着一些更新將會丟失? – Joey

+0

一些個人更新不會被執行,這是正確的。但是,由於您的更新正在更新UI,因此無論如何都不希望更新它們的頻率。即如果在將文本設置爲''文本'之間沒有任何框架被渲染,你不想做'label.setText(「X」)','label.setText(「Y」)','label.setText(「Z」 「X」並將其設置爲「Z」 - 中間更新永遠不會被用戶看到。 –

0

事實上,你說UI完全凍結了聲音,對我來說更像是一個死鎖狀態,而不是使用太多的Platform.runLater調用。有各種可用於檢測死鎖的工具。使用過多的Platform.runLater調用通常應該使系統變得更慢,因爲存在一個構建調用的隊列。