为什么Platform.runLater不检查它当前是否在JavaFX线程上?

为什么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

当使用JavaFX8时,我们需要通过
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%的情况下寻找的方法。