いいえ、あなたの要約が正しいとは思いません。通常、 をスローする他のメソッドを呼び出すメソッドを作成している場合は、そのメソッドもスローInterruptedException
を宣伝する必要があります。InterruptedException
ただし、依存しているメソッドが中断を通知した場合に何をすべきかについて適切な計画を持っている場合を除きます。
このような中断を吸収できるケースはまれです。おそらく、時間の経過とともに精度が向上する反復解を計算しているのに、呼び出し元のスレッドが中断されたときに、割り当てられた時間内に到達した解で十分であり、返すのに十分正しいと判断したとします。つまり、その解はまだメソッドの範囲内にあります。
想像:
private double improveUpon(double start) throws InterruptedException {
// ...
}
public double compute() {
double result = 0.0;
try {
do {
result = improveUpon(result);
} while (couldBeImproved(result));
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
return result;
}
代わりに、単に中断要求を尊重したい場合は、InterruptedException
関与せずにそうすることができます:
private double improveUpon(double start) {
// ...
}
public double compute() {
final Thread current = Thread.currentThread();
double result = 0.0;
do {
result = improveUpon(result);
} while (couldBeImproved(result) &&
!current.isInterrupted());
return result;
}
さらに別のバリエーションとして、メソッドがすべての作業を完了するか、完了できなかったことを呼び出し元に示す必要があり、そこに到達するまでに時間がかかるが、スレッドの中断を尊重したい場合を考えてみましょう。このようなもので十分です:
private double improveUpon(double start) {
// ...
}
public double compute() throws InterruptedException {
final Thread current = Thread.currentThread();
double result = 0.0;
do {
if (current.interrupted())
throw new InterruptedException();
result = improveUpon(result);
} while (!isAdequate(result));
return result;
}
ここで on を呼び出したことに注意してください。これには、スレッドの割り込みステータスが設定されている場合にクリアするThread#interrupted()
という副作用があります。そのメソッドが true を返す場合、呼び出し元として、その割り込みステータスを保持して通信する責任を受け入れたことになります。この場合、呼び出し元のスレッドを作成したと仮定せず、割り込みポリシーが何であるかを知るのに十分なスコープがここに表示されていないため、観察して採用した割り込みステータスを throwing で伝えました。InterruptedException
メソッドに「ブロッキング」というラベルを付けるのは、常に程度の問題です。すべてのメソッドは、呼び出し元を一定時間ブロックします。探している違いは、ユーザーがキーを押したり、ネットワーク経由でメッセージが到着したりするなど、何らかの外部入力を待機するメソッドをブロックするかどうかです。このような場合、スローするアドバタイズメントは、レイテンシーを制御する必要があるスレッドからInterruptedException
の呼び出し元がメソッドを安全に使用できることを呼び出し元に示します。あなたは、「これが完了するまでに時間がかかるかもしれませんが、あなたが待っているよりも長くはかかりません」と言っています. あなたは、「あなたがやめろと言うまで、私は走る」と言っているのです。これは、たとえば、3 つの条件のいずれかが発生するまでブロックすると脅迫する とは異なります。java.io.InputStream#read()
呼び出し元のスレッドが中断されています。
ほとんどの場合、決定は次の質問に答えることに帰着します。
- メソッドの要件を満たすために、スローするメソッドを呼び出す必要があります
InterruptedException
か?
- もしそうなら、私がその時点までに行った作業は、発信者にとって役に立ちますか?
- そうじゃないなら俺も投げればいい
InterruptedException
。
- throws を呼び出さない場合、呼び出しスレッドの割り込みステータス
InterruptedException
を尊重する必要がありますか?
- もしそうなら、私が中断されたことを発見するまでに私が行った作業は、私の発信者にとって役に立ちますか?
- そうでなければ、私は投げるべき
InterruptedException
です。
現在のスレッドの中断を検出して飲み込む状況は、通常、作成者であるあなたが問題のスレッドを作成し、run()
スレッドが中断されたらスレッドのメソッドを終了することを約束した場合に限定されます。これが「協調的取り消し」の概念です。スレッドの実行を停止する要求を観察し、できるだけ早く作業を終了してスレッドの呼び出しスタックを巻き戻すことで、その要求に従うことを決定します。繰り返しになりますが、スレッドのrun()
メソッドの作成者でない限り、スレッドの割り込みステータスを飲み込むと、呼び出し元や呼び出し先の他のメソッドの意図した動作が損なわれる可能性があります。
スレッドの中断ステータスThread#isInterrupted()
のトピックを調べて、 、Thread#interrupted()
、およびのメソッドに慣れることをお勧めしますThread#interrupt()
。それらを理解しInterruptedException
、飛行中の存在が true を返したことの代替表現Thread#isInterrupted()
、または true を返したことの丁寧な翻訳であることを理解したらThread#interrupted()
、これはすべてより理にかなっています。
学習するためにさらに例が必要な場合は、そう言ってください。ここに推奨事項を追加できます。