0

タイトルに示されているアイデアの多くの例の 1 つとして、java.util.concurrent.locks.AbstractQueuedSynchronizerの次のコードを検討してください。

1258    public final boolean tryAcquireSharedNanos(int arg, long nanosTimeout) throws Interrupted Exception {
1259        if (Thread.interrupted())
1260            throw new InterruptedException();
1261        return tryAcquireShared(arg) >= 0 ||
1262            doAcquireSharedNanos(arg, nanosTimeout);
1263    }

Thread.interrupted()ほとんどのブロッキング ライブラリ メソッドが、インスタンス メソッドではなく静的メソッドを呼び出すことによって割り込みに応答するのはなぜですかisInterrupted()。静的メソッドを呼び出すと、中断されたステータスもクリアされるため、タスク処理コードでさえ InterruptionException を飲み込んだ場合、呼び出し元が中断されたステータスを知る方法はありません。

4

3 に答える 3

5

InterruptedExceptionをキャッチした場合、中断されたフラグはすでにクリアされていることは常に真実です。例外自体は、その時点でのシグナル伝達メカニズムです。キャッチャーは、フラグを再度有効にするか、スレッドが終了するように直接注意する必要があります。

于 2012-07-16T09:09:55.250 に答える
1

基本的に、API /動作コントラクトは異なるはずだと考えているようで、「彼ら」がそれを自分の好みの方法ではなく、そのように設計した理由を知りたいと考えています。

答えられません。問題が議論され、決定が下されたとき、ここの誰も「部屋に」いませんでした。明確な答えが必要な場合は、元のデザイナーを追跡して尋ねる必要があります。

そして、とにかく問題は議論の余地があります...あなたがあなた自身のプログラミング言語を設計して実装することを計画していない限り。

于 2012-07-16T09:50:39.453 に答える
1

タイトルの質問に対する答えは、「実装すると直接Runnable公開されないため」です。isInterrupted()明らかに、フラグに影響を与えずにフラグにアクセスするのは簡単ですThread.currentThread().isInterrupted()が、それはここでのポイントではありません。ポイントは、それがThread.interrupted()主に行うべきことであるため、意図的に使いやすくなっているということです。

を使用するコードに関する苦情Thread.interrupted

スレッドが中断されているかどうかを確認している場合は、コード内でそれについて何かを行うことができるポイントにいる必要があります。そうでない場合、ポイントは何ですか? 定義されたメカニズムは、ループを静かに終了することを意図的に思いとどまらせます。割り込みに対処することを特に奨励しており、意図的に割り込みをスローして処理することを奨励しています。

isInterrupted疑わしいのはを呼び出すコードであり、 を呼び出すコードではありませんinterrupted。割り込みを静かに処理することを検討すべきではありません。劇的に処理するか、まったく処理しないようにする必要があります。Thread.currentThread.isInterrupted()呼び出し元ではなく、静かに例外を吸収して問題を引き起こしているのは呼び出し元ですThread.interrupted()

より信頼できる議論については Dr. Heinz M. Kabutz on Shutting down threads cleanly を参照してください。

于 2012-07-16T10:44:27.340 に答える