我在我們的一個項目中遇到了一個奇怪的問題。我們使用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