我在我们的一个项目中遇到了一个奇怪的问题。我们使用JUnit来运行我们的单元测试,并且前一段时间,我们开始并行运行pur测试来加速执行。大多数时候,一切都很好,但有时我们几乎所有的测试都失败了。在下一次运行中,他们都会再次通过,而不会更改任何代码。多线程和静态块
这些错误似乎表明某些静态实例未正确初始化或在多线程情况下初始化完成之前使用。 (我不能调试这个,因为这个问题从来没有一次露面在调试的时候 - >Heisenbug)
对不起,因为它试图重现消失的时候,我不能提供显示的bug最小工作示例。
具体的问题是:当声明一个像下面这样的变量时,当另一个线程调用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();
}
}
我确定它不是硬件相关的,因为它显示在不同制造商的不同机器上。测试正在使用服务器虚拟机。
谢谢
阿克塞尔
新A()或新B()是否开始新线程?你是否试图找出问题并创建一个能够再现问题的[SSCCE](http://sscce.org)? – assylias
因为我知道,使用整个类的静态字段和方法是一个不好的做法,尤其是使用多线程。为什么不创建非静态类并将其存储在静态字段中? – alaster
这就是在这里完成的。 a和b是提供预先计算值的类的实例。这两个类都是不可变的,并且有方法返回这些预先计算的值。计算是在相应的类构造函数中完成的。在访问时,只有检查参数,计算索引并返回包含以前计算值的数组元素。 – Axel