为什么Platform.runLater不检查它当前是否在JavaFX线程上?
当使用JavaFX8时,我们需要通过为什么Platform.runLater不检查它当前是否在JavaFX线程上?,java,javafx,javafx-8,Java,Javafx,Javafx 8,当使用JavaFX8时,我们需要通过Platform.runLater运行与GUI的交互,否则如果从另一个线程运行,它们将抛出异常 但是,Platform.runLater的实现从不检查它当前是否在JavaFX线程上 我写了以下方法: public static void runSafe(final Runnable runnable) { Objects.requireNonNull(runnable, "runnable"); if (Platform.isFxApplica
Platform.runLater
运行与GUI的交互,否则如果从另一个线程运行,它们将抛出异常
但是,Platform.runLater
的实现从不检查它当前是否在JavaFX线程上
我写了以下方法:
public static void runSafe(final Runnable runnable) {
Objects.requireNonNull(runnable, "runnable");
if (Platform.isFxApplicationThread()) {
runnable.run();
}
else {
Platform.runLater(runnable);
}
}
这确保它永远不会在非fx应用程序线程上运行
默认实现没有进行这种短路有什么原因吗?当调用函数时,函数名为“runLater”,我希望它稍后运行,而不是现在 在我看来,基于它的名称,实现正在做正确的事情: 在将来某个未指定的时间在JavaFX应用程序线程上运行指定的Runnable 此方法可以从任何线程调用,将Runnable发布到事件队列,然后立即返回给调用方。可运行项按其发布的顺序执行。传递给runLater方法的runnable将在传递给runLater的后续调用的任何runnable之前执行
如果不希望代码稍后运行,请不要要求代码稍后运行。这就是您基本上对代码所做的操作。
runLater
基本上是在FX线程可用时将您的Runnable放在队列中执行。可以通过非FX线程访问该方法。假设其他一些线程已将任务放置在runLater
队列中,然后再次调用runLater
,无论是否从FX线程调用,都应将新任务放置在该队列的尾部
由于您提出的短路,以前的任务基本上具有较低的优先级,这可能是不可取的。我见过有人在Swing中从EDT调用
EventQueue.invokeLater
。。。根据佳能的说法,这是一种合法的技术。所以JavaFX中的情况也是如此,除非我大错特错
然而,我个人对这项技术持怀疑态度。请参阅:所选答案使用invokeLater
,因为selectAll()
需要在调用之前完成所有当前EDT事件:此解决方案确实确保了selectAll
不能在其他EDT代码在此发生之前运行
但我认为,这个答案存在漏洞。请参阅我建议的答案(用Jython编写,但应该可以理解)。假设有人将“单击计数开始编辑”设置为1。更令人担忧的是,假设invokeLater
和selectAll
之间发生了不可预测的事情。除非您绝对确定自己根本没有其他机制,或者绝对确定两个线程的事件和对象完全“不耦合”,否则我个人认为应该避免从JavaFX线程调用runLater
并发总是在等着咬你。因此,最好谨慎使用这些技术 很高兴看到关于StackOverflow的好问题和好答案。我希望将此方法添加到
平台
,因为这是我在90%的情况下寻找的方法。