【发布时间】:2016-01-25 17:59:02
【问题描述】:
似乎有一个共识,即 JavaFX UI 线程的上限为每秒 60 次更新(1、2)。我的理解是更新意味着pulse。
脉冲是一个事件,它向 JavaFX 场景图指示它 是时候同步场景图上元素的状态了 棱镜。脉冲被限制为最大每秒 60 帧 (fps) 并在动画在场景图上运行时触发。甚至 当动画没有运行时,当有东西进入时会安排一个脉冲 场景图发生了变化。例如,如果一个按钮的位置是 改变,安排一个脉冲。
来源:https://docs.oracle.com/javafx/2/architecture/jfxpub-architecture.htm
为了弄清楚如果有超过 60 次对 Platform.runLater 的调用会发生什么,我编写了这个小程序:
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class HighUITraffic extends Application {
private int counter = 0;
private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
StackPane root = new StackPane();
Timer timer = new Timer();
TimerTask task = new TimerTask() {
@Override
public void run() {
long sheduleTime = System.currentTimeMillis();
System.out.println("Task "+counter+" run at "+sdf.format(new Date(sheduleTime)));
Platform.runLater(new RunInUI(counter));
counter++;
}
};
timer.schedule(task, 0, 10); // every 10ms => 100 per second
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
private static class RunInUI implements Runnable {
private final int counter;
public RunInUI(int counter) {
this.counter = counter;
}
@Override
public void run() {
long executionTime = System.currentTimeMillis();
System.out.println("Task "+counter+" executed in Application Thread at "+sdf.format(new Date(executionTime)));
}
}
}
我的期望是:
-
Runnables 堆叠出来,UI 线程穿插运行,然后执行所有排队的Runables。 - UI 线程执行前 60 个调用,然后进一步排队
Runables。
然而,在 Runables 排队并随后由 UI 线程一次性处理的最初延迟之后发生的情况是,两个线程按顺序运行:
任务 1281 运行于 2016-01-25T18:37:00.269 任务 1281 执行于 应用程序线程在 2016-01-25T18:37:00.269 任务 1282 运行于 2016-01-25T18:37:00.274 任务 1282 在应用程序线程中执行 2016-01-25T18:37:00.274 任务 1283 在 2016-01-25T18:37:00.279 运行
并且在一秒钟内有超过 60 个线程调用(我尝试了 100 和 200,没有任何区别)。
所以我很困惑:
- 我是否误解了上限为 60 个脉冲的概念?
- 这个小执行片段是否没有那么重,以至于可能超出限制?
我首先想知道的是,如果线程已达到其上限限制,则会在 UI 线程上推送Runables 会发生什么。是所有排队的Runables 在一次运行UI 线程中按顺序执行,还是只执行了一个Runable,其余的必须等待?第二种情况会导致严重的问题,即在 UI 线程上持续推送超过该限制的 Runables。
【问题讨论】:
标签: java multithreading javafx