使用Platform.runLater()使用多个线程冻结JavaFX UI

时间:2016-04-14 12:57:41

标签: multithreading javafx

我有一个JavaFX应用程序,它运行多个执行繁重计算的线程。问题是,过了一段时间UI完全冻结,但我只用Platform.runLater()

更新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 );
}

现在线程做很多东西,比如下载文件,但我想这不应该影响UI。他们偶尔会从界面上阅读,但这不应该是问题。

我认为通过使用platform.runlater(),用户界面无法冻结。

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

由于我没有任何修改用户界面的其他代码,这一定是问题所在。程序执行了很多很多的Platform.runLater() - s,是不是太多了? 或者多少钱太多了?还有其他应用程序具有流畅的UI,比我的更频繁地更新界面方式并且运行得很好。可能是什么问题?感谢。

2 个答案:

答案 0 :(得分:2)

从您的问题中确定无法确定,但听起来好像您只是通过多次调用Platform.runLater(...)来安排到FX应用程序线程的许多可运行程序。 &#34;有多少太多&#34;是不负责任的,因为它取决于许多因素,但通常你不应该更频繁地安排它们而不是消费它们。

通常,您可以通过仅在已执行计划的先前更新时安排对UI的新更新来执行此操作。有关执行此操作的技巧,请参阅Throttling javafx gui updates

答案 1 :(得分:0)

事实上,你说UI完全冻结声音对我来说更像死锁条件而不是使用太多的Platform.runLater调用。有各种工具可用于检测死锁。使用太多的Platform.runLater调用通常只会使系统变慢,因为存在一个调用队列。