JavaFX 线程始终可运行

标签 java swing javafx profiling

为什么JavaFX应用程序线程总是RUNNABLE?

来自 YourKit 分析器的以下屏幕(VisualVM 显示类似的图片):

enter image description here

黄色部分表示等待状态,浅绿色-可运行,深绿色表示线程实际工作(在堆栈跟踪中可见)

Swing 的 EDT 等待事件并等待其他事件,但 JavaFX 线程实际上是做什么的?其100%可运行状态是否会导致性能泄漏?

最佳答案

线程状态背景

根据Thread.State.RUNNABLE文档:

Thread state for a runnable thread. A thread in the runnable state is executing in the Java virtual machine but it may be waiting for other resources from the operating system such as processor.

大多数时候,JavaFX 应用程序线程正在等待操作系统级别的回调,因此它在分析器中显示为 RUNNABLE,即使它通常在等待。这是因为等待发生在 native 代码中,而不是 JVM 中的 sleep 式调用。

从这个Java thread state UML diagram可以看出Java线程进入不同的状态需要不同的方法。在 Swing 中,其中一种方法用于使 EDT 进入等待状态,但在 JavaFX 中不使用类似的方法。

JavaFX 的工作原理

architecture of the JavaFX system基于定时脉冲,默认情况下每秒触发 60 次。为了获得平滑的动画显示而不出现图像撕裂,(我认为)系统可以启用垂直同步计时器,以便脉冲与显示同步。标准 JVM 不知道操作系统特定的 vsync 计时器,因此 JavaFX 系统使用 native 代码使 JavaFX 应用程序线程等待操作系统提供的 vsync 计时器。

这不是问题

Whether its 100% runnable state may cause performance leaks?

不,我不认为状态会导致性能泄漏。

需要注意的一件事是,JavaFX 应用程序线程适用于 UI 更新,因此默认情况下,在其上运行的内容每秒最多运行 60 次。因此,如果您使用 PauseTransition 之类的东西并将暂停持续时间设置为 Duration.millis(10),则暂停实际上不会是 10 毫秒,而是 60 秒(大约 16 毫秒)。

如果你的东西对时间非常敏感,你可能最好使用 ScheduledThreadPoolExecutor 之类的东西。或一些高分辨率操作系统 native 计时器,但对于大多数人来说,这并不是他们需要担心的真正考虑因素,因为他们不会处理如此高分辨率的计时。

使用 JavaFX 应用程序线程时的主要性能考虑因素只是确保完成所有工作并释放线程(最好在六十分之一秒内),以便 UI 和事件处理不会被保留由您的应用程序决定,但这种考虑与 Swing 相同,因此没有什么新内容。

脉冲定义

来自 JavaFX 架构概述(帮助理解脉冲如何与事件处理相关):

When a pulse is fired, the state of the elements on the scene graph is synchronized down to the rendering layer. A pulse enables application developers a way to handle events asynchronously. This important feature allows the system to batch and execute events on the pulse. . . . The Glass Windowing Toolkit is responsible for executing the pulse events. It uses the high-resolution native timers to make the execution.

免责声明

对此答案的免责声明是,其中一些内容是我的猜测,因此可能略有不正确,但我认为这可能是对事实的合理近似。

更多信息

如果您有兴趣进行更多调查,可以查看TimerWinTimer open-jfx 代码库中的代码或其他代码,或者在 openjfx-dev 上询问更多 JavaFX 架构问题JavaFX 开发人员邮件列表。那里的开发人员比我更了解这些事情,并且能够做一些事情,例如验证我的猜测,例如脉冲是否垂直同步。

关于JavaFX 线程始终可运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26910159/

相关文章:

javafx - 如何在 FXML 中的对象元素之前创建对对象的引用?

java - 在 Java Swing 中,如何将数组中的数据从一个表单传递到下一个表单?

java - 完全删除 jtable 网格(单元格边框)

java - 无法查看缓冲图像

java - 为什么我无法使用 Controller 传递值并在场景中显示?

尽管代码正确,但 JavaFX 程序无法运行?

java - 如何根据带有 "0' s"的文本字段输入查询 SQLite 数据库?

java - 我应该将 try-catch block 与断言一起使用吗

运行某些小程序时 java 出现不安全消息

java - 选择一个后裁剪图像的最佳方式