- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
JavaFX UI 线程上限为每秒 60 次更新(1、2)似乎是一种共识。据我了解,更新意味着 pulse
。
A pulse is an event that indicates to the JavaFX scene graph that it is time to synchronize the state of the elements on the scene graph with Prism. A pulse is throttled at 60 frames per second (fps) maximum and is fired whenever animations are running on the scene graph. Even when animation is not running, a pulse is scheduled when something in the scene graph is changed. For example, if a position of a button is changed, a pulse is scheduled.
来源:https://docs.oracle.com/javafx/2/architecture/jfxpub-architecture.htm
为了弄清楚如果对 Platform.runLater
的调用超过 60 次会发生什么,我编写了这个小程序:
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)));
}
}
}
我的期望是:
Runnable
被堆叠起来,UI线程穿插运行,然后执行所有排队的Runable
。Runable
排队。然而,在 Runables 排队并由 UI 线程一次处理所有初始延迟后发生的事情是,这两个线程按顺序运行:
Task 1281 run at 2016-01-25T18:37:00.269 Task 1281 executed in Application Thread at 2016-01-25T18:37:00.269 Task 1282 run at 2016-01-25T18:37:00.274 Task 1282 executed in Application Thread at 2016-01-25T18:37:00.274 Task 1283 run at 2016-01-25T18:37:00.279
并且在一秒钟内有超过 60 个线程的调用(我尝试了 100 和 200,没有任何区别)。
所以我很困惑:
我首先想知道的是,如果线程已达到其上限限制,推送到 UI 线程的 Runable
会发生什么情况。是所有已排队的 Runable
在 UI 线程的一次运行中按顺序执行,还是只有一个 Runable
执行而其余的必须等待?第二种情况会导致严重的问题,当在 UI 线程上连续推送超过该限制的 Runable
时。
最佳答案
脉冲上限为 60fps。提交给 FX 应用程序线程的 Runnable
不是。
据我了解,有两个线程:FX 应用程序线程和棱镜渲染线程。 FX 应用程序线程使用队列中的 Runnable
并执行它们。 prism 渲染线程每秒最多执行 60 次,与 FX Application Thread 同步(从而暂时阻止它执行新的 runnable)并渲染帧,然后释放 FX Application Thread。
因此,FX Application Thread 会尽快执行您的Runnable
,并且不限于每 1/60 秒执行一个 runnable;但它不会在帧渲染期间从队列中获取新的可运行对象。 (用户事件在 FX 应用程序线程上以类似于您发布的 Runnable
的方式处理。)
所以有几种方法可以让坏事发生。一种是在 FX 应用程序线程(无论是在事件处理程序中还是在 Runnable
中发布到 Platform.runLater()
)上执行需要很长时间的代码。这样做会阻止 Prism 渲染线程与 FX 应用程序线程同步,这意味着在可运行对象完成之前无法渲染下一帧。另一种方法是用过多的 Runnable
轰炸 FX 应用程序线程,这样队列的增长速度快于它们的消耗速度。 (本质上,由于队列总是有可用的东西,因此 FX 应用程序线程在这些情况下会变成繁忙的线程,并且不能保证 prism 渲染线程能够运行。)
因此,对您的问题的直接回答是 Runnable
按照它们发布的顺序执行,尽可能迅速地在单个线程上执行。上限为 60 fps 的帧渲染将暂时停止使用队列中的 Runnable
。
在伪代码中,我猜测(这只是我对它如何工作的直觉,这不是基于源代码)FX 应用程序线程看起来像 p>
while (fxToolkitRunning()) {
Runnable runnable = runnableQueue.take(); // block until something available
acquireLock();
runnable.run();
releaseLock();
}
棱镜渲染线程看起来像这样:
while (fxToolkitRunning()) {
while (! timeForNextFrame()) {
sleep(timeUntilNextFrame());
}
acquireFXApplicationThreadLock();
if (sceneNeedsUpdating()) {
renderFrame();
}
releaseFXApplicationThreadLock();
}
关于JavaFX FPS 上限为 60 FPS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34999121/
我不知道这是不是问这种问题的最佳地点, 我看到一些 JavaFX伙计们,重新标记 一些问题通过替换 javafx来自 javafx-2并采用新的 javafx-8 .它被弃用了还是什么? 编辑 : 不
错误本身: Error:java: invalid flag: --add-modules=javafx.fxml,javafx.graphics,javafx.controls,javafx.bas
这个想法是让一个应用程序在每个显示器上显示两个不同的窗口(阶段),该应用程序应该知道计算机有多少个显示器及其分辨率。 javafx有可能吗? 最佳答案 对于当前版本的 JavaFX (2.2),您可以
我正在将我的项目从 javafx 1.3 转换为 javafx 2.1。但我对 javafx.lang 有疑问包裹。 最佳答案 JavaFX 1.3 lang 包内容被拆分并移至下一个位置: 时长变为
当我尝试将标签添加到 gridpane 中时,如第二张图片所示,它不起作用。我已经尝试了很多东西,比如添加 CSS,但它仍然无法正常工作。为什么第 113 和 114 行不起作用? (opcje.se
我有一个JavaFX ContextMenu分配给滚动面板的鼠标右键单击。它会打开,但在滚动 Pane 外部单击时不会关闭。我可以在滚动 Pane 中添加另一个鼠标事件以将其隐藏,但这只能解决1个问题
我有一个tableview,其中附有一个可观察到的自定义类对象的列表(类类型:SalesInvoiceNetSale)。该表中的所有数据都可以正常显示。可观察列表中的最后一项是总计行(类类型:Sale
关闭。这个问题需要更多 focused .它目前不接受答案。 想改进这个问题?更新问题,使其仅关注一个问题 editing this post . 2年前关闭。 Improve this questi
我想知道如何在JavaFX中绘制半圆。我尝试使用Shape和QuadCurve,但无法制作出完美的半圆。 这是我要绘制的图片: 最佳答案 您链接的图片实际上是一个半圆环。您可以通过绘制嵌套的2条圆弧和
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
我正在寻找 JavaFX 支持的图像类型(最新)列表,例如PNG、JPEG、TIFF。不同的搜索引擎没有帮助......知道从哪里开始吗? 更特别的是,我对 16 位灰度图像(不同格式)和罕见的受支持
我希望在 javafx 中让标签每 0.1 秒闪烁一次。文本显示在后台运行的 ImageView gif 的顶部。我将如何去做,或者您对最佳方法有什么建议? 谢谢 最佳答案 @fabian 的解决方案
我需要测试所选项目的值以调用不同的方法,因此我编写了添加侦听器的代码,但是该代码生成语法错误 @FXML private JFXComboBox cmbComp; cmbComp.valuePrope
我正在 Javafx 中编写一个非常简单的应用程序,其中舞台上有一个带有文本框的按钮作为一个场景。现在,我想要的行为是,当我单击按钮时,我可以使用另一个按钮加载另一个场景和舞台上的一个文本框,然后删除
编辑:如果用户单击“删除”以删除 ListView 中的项目,我会弹出一个警告框。它有效,但我希望它能超越原来的舞台。它出现在我的第一台显示器上。有什么方法可以设置警报显示时的位置吗? 请注意,“所有
我想使用 JavaFX 编写一个笔画绘图应用程序。我有一个压敏绘图板,如果能够读取笔的压力和倾斜值,那就太好了。 JavaFX 有一个 API 可以处理鼠标、触摸和滑动输入,但似乎没有任何东西可以产生
我在 JavaFX 中使用条形图和折线图。当我使两个图表大小相同并将它们放在同一位置时,它们完美地相互重叠。我如何使折线图显示在条形图的顶部。 目前我已将它们的不透明度设置为 0.7,这样它们“看起来
此问题与 this 相关。现在我想为字段值等于某个值的行着色。 @FXML private TableView tv_mm_view; @FXML private Ta
我有一个程序,可以生成高度图(0-255 的整数的 2D 数组),并使用 Shape3D“Box”对象为每个“像素”构建 3D View ,其高度与其在高度图中的值成比例。这会创建一个看起来很酷的四四
我想为 JavaFX 创建上下文菜单。这是我测试过的代码。但是由于某种原因,当我右键单击树节点时没有上下文菜单。你能帮我找出我的错误吗。 import java.util.Arrays; import
我是一名优秀的程序员,十分优秀!