Java 如何检查FX应用程序线程策略冲突

Java 如何检查FX应用程序线程策略冲突,java,multithreading,javafx,Java,Multithreading,Javafx,我正在使用的一个应用程序大量使用JavaFX,我注意到我们不断遇到上面提到的表单的异常。该问题提到,在FX应用程序线程之外创建节点时可能会发生异常 我想找到任何可以从FX线程访问FX对象的地方,但是应用程序太大了,通过检查来实现这一点是不切实际的。我看到了一个,但还没有找到任何类似的JavaFX。这里最常提到的Swing解决方案涉及一个定制的repaitmanager,这是一个Swing特定的接口 因此:我如何(如果有的话)找到代码访问除FX应用程序线程以外的线程上的JavaFX对象的位置,而不

我正在使用的一个应用程序大量使用JavaFX,我注意到我们不断遇到上面提到的表单的异常。该问题提到,在FX应用程序线程之外创建节点时可能会发生异常

我想找到任何可以从FX线程访问FX对象的地方,但是应用程序太大了,通过检查来实现这一点是不切实际的。我看到了一个,但还没有找到任何类似的JavaFX。这里最常提到的Swing解决方案涉及一个定制的
repaitmanager
,这是一个Swing特定的接口

因此:我如何(如果有的话)找到代码访问除FX应用程序线程以外的线程上的JavaFX对象的位置,而不必手动检查应用程序的所有FX代码



注意:我完全知道在fx线程之外与fx对象交互是个坏主意。一旦发现违反策略,我也完全知道我可以使用
Platform.runLater(()->{/*fx code*/})以在fx线程上执行操作。我的问题是如何找到违规行为。

可能不太理想,但一个解决方案是在
java.lang.ClassLoader.loadClass(字符串名称,布尔解析)
中放置一个条件断点,条件是:

name.startsWith("javafx") && 
    !Thread.currentThread().getName().equals("JavaFX Application Thread")
然后,无论何时从javafx包加载新类,都可以检查这些类是否正在FX线程上加载。它当然不会捕获所有违规行为,但当线程使用FX代码导致加载以前未使用过的FX类时,它会通过暂停违规线程让您知道

(如果可以将
!javafx.application.Platform.isFxApplicationThread()
添加到断点条件,那就太好了,但是在Eclipse Luna中,我很难让它正常工作。)

还要注意的是,并不是每次点击这个按钮都是一个实际的违规行为——一个类可以在没有实例化和/或交互该类的实际对象的情况下加载。例如,如果以下构造函数是从非FX线程调用的,它可能会设置断点,尽管这并不危险:

public class MyClass{
    Label l = null; //Loading & instantiating MyClass loads
                    // the Label class, but doesn't necessarily
                    // violate the FX threading policy

    public MyClass(){

    }
}

不过,这个解决方案总比什么都没有好(我已经发现了一个实际的冲突)。

Platform.runLater(新的Runnable(){@Override public void run(){/*在JFX线程上做一些事情*/})@SnakeDoc:请参阅添加的注释。我知道如何在发现线程策略冲突时修复它们。实际上,我不认为你有任何方法可以做到这一点。你是否尝试过在分析器下在应用程序线程上达到峰值?它应该提供一些关于哪个线程正在做什么以及什么时候做的信息。也许不完全是你想要的,但可能会有帮助。JProfiler很棒,但Oracle JDK(现在也可能是OpenJDK)附带了一个免费的探查器JVisualVM。@SnakeDoc:我不知道如何最好地利用探查器来查找我要查找的信息。我想我可以周期性地强制线程转储,并在FX堆栈中的某个位置达到峰值,但以这种方式捕获违规者的机会充其量只是偶然的(如果一个线程在FX堆栈中只花费1%的cpu时间怎么办?足以引起bug,但不太可能被快照捕获)。试试FindBugs,我很想知道它是否抓住了这种类型的问题(因为它可能相当普遍)。