4

私たちのプロジェクトの1つで奇妙な問題に直面しています。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 に答える