多线程和静态块

时间:2012-06-19 08:57:44

标签: java initialization static-block

我在其中一个项目中遇到了一个奇怪的问题。我们使用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。

谢谢,

阿克塞尔

2 个答案:

答案 0 :(得分: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();
    }

}

答案 1 :(得分:0)

如果AB创建线程或以其他方式在不同的线程上执行代码,则可能会出现问题。无论如何,你真的希望静力学是不可变的。

理论上,如果存在循环依赖关系,则可以查看部分初始化的类,但这种可能性很小。