JavaFX中的Platform.runLater和Task

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (293)

我一直在做这方面的研究,但我仍然非常困惑,至少可以说。

任何人都可以给我一个何时使用Task和何时使用的具体例子Platform.runLater(Runnable);吗?究竟有什么区别?何时使用这些方法是否有一条金科玉律?

还纠正我,如果我错了,但不是这两个“Objects”的方式在GUI中的主线程内创建另一个线程(用于更新GUI)?

提问于
用户回答回答于

使用Platform.runLater(...)快速和简单的操作和Task复杂的和大的操作。

  • 用例 Platform.runLater(...)
  • 使用案例Task:Ensemble App中的任务示例

示例:为什么我们不能Platform.runLater(...)用于长时间计算(摘自下面的参考文献)。

问题:后台线程数从0到100万,并在UI中更新进度条。

代码使用Platform.runLater(...)

final ProgressBar bar = new ProgressBar();
new Thread(new Runnable() {
    @Override public void run() {
    for (int i = 1; i <= 1000000; i++) {
        final int counter = i;
        Platform.runLater(new Runnable() {
            @Override public void run() {
                bar.setProgress(counter / 1000000.0);
            }
        });
    }
}).start();

这是一个可怕的代码块,是一种反对自然的罪行(以及一般的编程)。首先,只要看看Runnables的这种双重嵌套,就会失去脑细胞。其次,它将用小的Runnables来淹没事件队列 - 事实上有一百万个。显然,我们需要一些API来编写后台工作人员,然后与UI进行通信。

使用任务代码:

Task task = new Task<Void>() {
    @Override public Void call() {
        static final int max = 1000000;
        for (int i = 1; i <= max; i++) {
            updateProgress(i, max);
        }
        return null;
    }
};

ProgressBar bar = new ProgressBar();
bar.progressProperty().bind(task.progressProperty());
new Thread(task).start();

它没有在前面的代码中展示的缺陷

参考: JavaFX 2.0中的工作线程

用户回答回答于
  • Platform.runLater:如果您需要从非GUI线程更新GUI组件,则可以使用该组件将更新放入队列中,并尽快由GUI线程处理。
  • Task实现Worker当你需要在GUI线程之外运行一个长任务时使用的接口(以避免冻结你的应用程序),但仍需要在某个阶段与GUI进行交互。

如果你对Swing很熟悉,前者相当于SwingUtilities.invokeLater后者,后者则相当于概念SwingWorker

扫码关注云+社区