如何检查FX应用程序线程策略违规

时间:2015-12-11 22:46:52

标签: java multithreading javafx

我正在使用的应用程序大量使用JavaFX,我注意到我们不断获得this open jdk issue中提到的表单的例外情况。该问题提到当您从FX应用程序线程创建节点时可能发生异常。

我想找到FX对象从FX线程访问的任何地方,但是应用程序足够大,以至于通过检查这样做是不切实际的。我看到了similar question and answer for Swing,但是我们无法找到类似JavaFX的内容。最经常提到的Swing解决方案涉及一个自定义RepaintManager,这是一个特定于Swing的界面。

所以如何(如果有的话)我可以在FX应用程序线程以外的线程上找到代码访问JavaFX对象的地方,而无需手动检查所有应用程序的FX码?

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

1 个答案:

答案 0 :(得分:0)

也许不理想,但一种解决方案是将条件断点放在java.lang.ClassLoader.loadClass(String name,boolean resolve)中,条件为:

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(){

    }
}

然而,解决方案总比没有好(我已经发现了一个实际的违规行为)。