2

InterruptedException本番コードからを発生させる統合テストを作成しようとしています:

@Test
public void test() {
    productionObject = new ProductionObject(
            com.google.common.util.concurrent.MoreExecutors.sameThreadExecutor());
    Thread.currentThread().interrupt();
    assertThat(productionObject.execute(), equalTo(defaultResponse));
}

内部productionObjectの実装:

try {
    for (Future<T> future : executorService.invokeAll(tasks))) {
        results.add(future.get());
    }
    return results;
} catch (InterruptedException e) {
    Thread.currentThread().interrupt(); // preserve interrupt flag
    return defaultResponse;
}

私が見る内部AbstractQueuedSynchronizer.acquireSharedInterruptibly()

  if (Thread.interrupted())
        throw new InterruptedException();

したがって、このテストは一貫して合格することを期待しています。

私たちのビルド サーバーでこれが失敗するのを見てきました (resultsではなく が返されますdefaultResponse)。私は失敗をローカルで再現することができず、while (true) ループでテストを実行し、ソフトウェア レンダリングで glxgears を実行してより高い負荷をシミュレートしました ;-) 誰でも私の間違いを見つけることができますか?または私を助けることができるツールを提案しますか?

4

3 に答える 3

1

変。私はあなたと同じようにコードを読みました。そうですか:

  1. FutureTask.get()を呼び出しますSync.get()。ここで扱っていると思いFutureTaskます。
  2. Sync.get()通話Sync.innerGet()
  3. Sync.innerGet()呼び出しacquireSharedInterruptibly(0)ます。
  4. コードは次のとおりです。

    if (Thread.interrupted())
        throw new InterruptedException();
    

これは常にスローされると思います。ある種の競合状態があるため、スレッドは中断されたことをまだ認識していないのでしょうか? スレッドを中断した後、100 ミリ秒スリープしようとしましたか?

マルチ CPU Mac で次のテストを実行したところ、失敗することはなかったので、競合状態のようには見えません。少なくとも私のアーキテクチャと JRE バージョン 1.6.0_41 では。

for (long i = 0; i < 10000000; i++) {
    Thread.currentThread().interrupt();
    assertTrue(Thread.interrupted());
}
于 2013-02-21T16:11:23.603 に答える
0

Callableテストメソッド自体からではなく、内部からスレッドを中断することで、これを「修正」しました。これにより、への呼び出しの近くで中断が発生しますacquireSharedInterruptibly()

コードパスのどこかで割り込みフラグがクリアされることがあると想像することしかできません(おそらく、テストメソッドを並行して実行しているJUnitまたはMavensurefireによって)。おそらく、競合状態を修正するのではなく、競合状態の可能性を減らしただけです:-/

于 2013-02-22T10:38:44.207 に答える
0

このコンテキストで使用sameThreadExecutor()すると、タスクの 1 つで割り込みが発生する可能性があるため、実際には逆効果になる可能性があります。それ以外の場合、コードは正常に見えます。実際の他のスレッドをキックオフしてみて、タスクの 1 つが割り込みを待つのに十分な時間待ちます。

于 2013-02-21T16:15:30.900 に答える