在 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/