You*_*f13 5 java multithreading javafx
以下两个简单的片段执行相同的操作,"Hello, world"每秒打印一次。但它们之间有什么区别呢?什么时候应该使用线程,什么时候应该使用时间轴。Timeline 内部是否启动一个线程?如果没有,如何在不阻塞主线程的情况下每秒执行一次打印?
Timeline timeline = new Timeline(new KeyFrame(Duration.seconds(1), e -> System.out.println("Hello, world")));
timeline.setCycleCount(-1);
timeline.play();
Run Code Online (Sandbox Code Playgroud)
new Thread(() -> {
while (true) {
System.out.println("Hello, world!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
Run Code Online (Sandbox Code Playgroud)
而且,在第二个片段中,如果我这样做Thread.sleep(some_volatile_variable_of_main_thread_that_changes_overtime),我如何使用Timeline.
该类Thread是标准 Java API 的一部分,代表后台线程。当 a启动时,其方法或其自己的方法Thread中的代码基本上与其他正在运行的线程并行执行。这允许可能需要很长时间才能运行的代码得以执行,而不会延迟可以“同时”运行的其他代码。使用此功能的程序员的代价是,如果数据在不同线程之间共享,则必须非常小心,以确保在任何单个线程中以一致的状态读取数据,并且数据是“活动的”:也就是说,数据会发生变化实际上,在一个线程中对数据所做的操作是在其他线程中观察到的。Runnablerunrun
相比之下,Timeline它是 JavaFX 框架的一部分,特别是其动画 API 的一部分。当 JavaFX 应用程序启动时,称为 FX 应用程序线程的线程开始运行。该线程在循环中运行,负责渲染 UI 和处理用户事件(除其他外)。UI 渲染发生在“脉冲”上,(在当前版本中)目标是每秒发生 60 次。由于上面提到的数据同步问题,对 UI 的所有更改都必须在 FX 应用程序线程上进行。此外,FX 应用程序线程上的代码不得长时间运行(因此它不能使用 暂停sleep(),或通过 IO 读取大数据集),因为它会阻止线程渲染 UI。
A 的Timeline工作原理是具有一组KeyFrames,每个 s 指定一个时间(以 a 的形式Duration,自时间线启动以来测量)和一个事件处理程序和/或KeyValue. 在 FX 应用程序线程的每个脉冲上,如果 aTimeline正在运行,FX 应用程序线程循环将检查是否到了触发任何事件处理程序的时间。对于KeyValues ,如果该值是可插值的(例如,是数字,或实现 )Interpolatable,则将通过计算经过的时间作为下一个 的时间的比例来计算其值KeyFrame。
Timelines 对于简单的动画很有用(例如,通过在窗格中移动节点,通过使用KeyValue指定其布局位置或平移坐标等的 s),也可用于在特定时间执行一组离散的 UI 更新(例如,显示并在“记忆”游戏中隐藏图像)。
最后:
KeyFrame附加到 a 的事件处理程序中的代码Timeline可能会更新 UI,因为它保证在 FX 应用程序线程上执行KeyValueKeyFrame作为a的一部分更新的 sTimeline可能是屏幕上显示的 UI 元素的属性KeyFrame不得阻止执行或执行长时间运行的任务Timeline将失败,因为没有 JavaFX 应用程序线程来执行更新。反过来:
Thread 不得更新 UI 元素(或其属性)。JavaFX 和 Java Swing/AWT 都是如此请注意,java.util.Timer和它关联的TimerTask(它们是标准 Java API 的一部分)在Timer. Timer这意味着,虽然和的 APITimerTask看起来有些相似Timeline,但它们必须遵守后台线程的规则(不得更新 UI 等)。
| 归档时间: |
|
| 查看次数: |
2045 次 |
| 最近记录: |