2016-04-14 234 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调用通常应该使系统变得更慢,因为存在一个构建调用的队列。