我的JavaFx应用程序在后台线程上从API读取数据(或者用于测试它是在应用程序启动时从本地存储器预加载),然后它处理并将数据设置为直接绑定在我视图中的属性上的模型。由于处理和设置数据以模型更改组件中显示的文本,因此使用Platform.runLater()
调用它。通常,当它被调用时,它消耗大约2%的CPU,但是如果我运行应用程序更长的时间,数据处理上的CPU消耗会稍微增加(对于GUI线程来说,数据处理可能太多)。例如,它在1小时内达到+ 4%左右。
然而,我认为奇怪的行为是,当我锁定Windows并离开几分钟然后回来时,数据处理的CPU使用率从8%变为17%,然后保持这么高。这是否意味着当Windows屏幕被锁定时,GUI线程不会运行?在我看来似乎没有,然后当它解锁时,GUI线程被Platform.runLater()
调用淹没。但是当它不处理数据时,它消耗了0%的CPU,所以我真的很困惑。
有谁知道这会导致什么?当窗口被锁定时,GUI线程是否真的停止工作?
编辑:
我已经发现处理收到的数据对于UI线程来说可能是一个过于密集的任务,我试图对其进行优化(在后台线程上进行大部分处理,然后只用{{1调用设置数据) }}。 后台代码下载的PoF非常简单,看起来像这样:
Platform.runLater
在 Thread updateDaemon = new Thread(() -> {
try {
while (true) {
TimeUnit.SECONDS.sleep(5);
processMarketStateData(view.getTable(), data);
}
}
}
catch (InterruptedException e) {
logger.error("Background worker interrupted", e);
}
});
updateDaemon.setDaemon(true);
updateDaemon.start();
我做了一些处理,然后设置数据到UI线程上的模型。但我真正感到好奇的是奇怪的CPU使用行为。当更新线程处于休眠状态且我不与UI交互时,CPU使用率为0%。当processMarketStateData
占用少量CPU时,它再次为0%,直到更新线程结束其睡眠状态。但是由于一些奇怪的原因,在几次processMarketStateData
调用后,CPU使用率越来越高。我上升了一小部分,比如50次通话后的1%,可能更多。甚至更奇怪的是,当Windows屏幕被锁定时,它会减少调用以产生这种奇怪的行为。当它变得非常疯狂并且它已经占用了大约20%的CPU用于呼叫时,它仅在processMarketStateData
呼叫时变高,其余时间它是0%。经过很长时间(几个小时)的测试后,我最终处于应用程序占用了25%CPU并且UI响应不足的状态。请注意,有2个这些线程同时运行。
我的实际问题不是"为什么我的ui在处理数据时会滞后",这不是很难找到,但它是"为什么它的行为方式呢?" 我希望这个编辑能让我的问题变得更好。
EDIT2:另一个奇怪的行为是,如果我将应用程序最小化一段时间并自动更新并打开它,那么它是黑色窗口一段时间,但是没有自动更新的应用程序是可以的。这真的让我觉得当应用程序最小化或Windows屏幕被锁定时,javaFX UI线程不会运行。可悲的是,我找不到这个。
答案 0 :(得分:1)
这些链接可能会对您有所帮助 Execute task in background in JavaFX https://docs.oracle.com/javase/8/javafx/interoperability-tutorial/concurrency.htm https://docs.oracle.com/javafx/2/threads/jfxpub-threads.htm
这可能是你在UI线程中执行cpu密集型任务。请提供一些代码示例。
您可以使用服务类进行cpu密集型计算,然后更新plateform.runlater调用中的ui。
答案 1 :(得分:0)
似乎我找到了真正的问题并修复了它。不幸的是,除非我愿意分享我的整个项目,否则你将无法帮助我。问题是,有processMarketStateData
方法调用的方法根据收到的数据设置样式。问题是它没有检查样式的存在而调用node.getStyleClass().add(style)
。因此,在15分钟之后,node.getStyleClass()
的大小约为300.在添加该检查后,似乎一切运行正常,并且最多占用CPU的2%。