JavaFX 时间线与 ScheduledExecutorService

标签 java javafx scheduled-tasks

在 JavaFX 8 项目中,您可以像这样使用 javafx.animation.Timeline:

Timeline timeline = new Timeline(
            new KeyFrame(Duration.millis(250),
                         actionEvent -> {
                               updateTemperature();
                         }
            )
    );
timeline.setCycleCount(Animation.INDEFINITE);
timeline.play();

或者您可以使用 ScheduledExecutorService 进行非常类似的操作:

executorService.scheduleAtFixedRate(this::updateTemperature, 0, 250, TimeUnit.SECONDS);

是否有使用其中一种而不是另一种的“最佳实践”?

最佳答案

与大多数 UI 工具包一样,在 JavaFX 中,您不得从专用 UI​​ 线程(在 JavaFX 中为 FX 应用程序线程)之外的任何线程访问作为显示一部分的 UI 组件。此外,需要(或可能需要)时间运行的代码(例如,具有阻塞调用,如 I/O 或网络)不应在 UI 线程上执行,因为这会使 UI 无响应。

您发布的两个代码片段在线程方面有很大不同。 ScheduledExecutor 将在后台线程(即不是 FX 应用程序线程)上执行 updateTemperature()。如果 updateTemperature() 需要很长时间才能运行,则这是合适的;但如果它访问 UI,它可能会抛出异常(或者更糟糕的是,有可能使 UI 处于不一致的状态)。

相比之下,Timeline 不会创建新线程,而是在 FX 应用程序线程上执行 updateTemperature()。如果 updateTemperature() 访问 UI,则必须在此线程上执行,这是一种便捷的方法。如果运行时间较长(我认为不会,因为每秒调用它 4 次),则会导致 UI 无响应。

关于JavaFX 时间线与 ScheduledExecutorService,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41246545/

相关文章:

java - 在 Maven 的测试范围内从 Eclipse 运行卡尺

JavaFX 8 : How to remove the last white pixel from the combobox list

image - 如何在 JAVAFX 中加载计算机目录图像

mysql - 有没有比使用 MySQL Schedule events 更好的方法来更新数据库表中的列?

java - 拖放不适用于 java 中的 chrome webdriver

java - LWJGL Javadoc 及其描述?

windows - 如何使用任务计划程序定期打开网页

asp.net-web-api - 来自 System.Web.Http.HostAuthenticationFilter 的 OperationCanceledException

java - 如果用户输入String而不是Int,有什么可能的异常(exception)情况?

java - 使用 Maven 生成 JavaFX 项目