4

我在我们的一个项目中遇到了一个奇怪的问题。我们使用 JUnit 来运行我们的单元测试,前段时间,我们开始并行运行 pur 测试以加快执行速度。大多数时候,一切都很好,但有时,我们几乎所有的测试都会失败。在下一次运行时,它们都再次通过而没有更改任何代码。

这些错误似乎表明某些静态实例未正确初始化或在多线程情况下完成初始化之前未使用。(我无法调试这个,因为调试时问题从未出现过 -> Heisenbug。)

抱歉,我无法提供显示该错误的最小工作示例,因为它在尝试重现时会消失。

具体问题是:当像下面这样声明一个变量时,当另一个线程调用 foo() 或 bar() 时,是否有可能没有完成 a 或 b 的初始化?我认为可以保证在调用任何方法之前执行静态块。或者可能存在类加载器问题?还是 JRE 中的已知错误(我们目前停留在 1.6.0_21,我们的 IT 部门尚未提供更新的版本)?

class C {
    private static final A a;
    private static final B b;

    static {
        a = new A(...);
        b = new B(...);
    }

    public static void foo() {
        useA();
    }

    public static void bar() {
        useB();
    }

}

我确信它与硬件无关,因为它出现在不同制造商的不同机器上。测试使用服务器 vm。

谢谢,

阿克塞尔

4

2 回答 2

0

如果创建线程或在不同线程上执行代码,A可能会出现问题。B无论如何,你真的希望静态是不可变的。

如果存在循环依赖关系,理论上有可能看到一个部分初始化的类,但这不太可能。

于 2012-06-19T10:30:35.563 回答
0

这很可能是由于并发问题,特别是如果你正在调用static东西。尝试同步您的线程,如下所示:

class C {
    private static final A a;
    private static final B b;

    static {
        a = new A(...);
        b = new B(...);
    }

    public synchronized static void foo() {
        useA();
    }

    public synchronized static void bar() {
        useB();
    }

}
于 2012-06-19T09:04:18.363 回答