synchronized (Foo.class) {
while (someCondition) {
try {
Foo.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
このスレッドは、他のスレッドが呼び出されたとき、interrupt()
またはnotify()
このスレッドで起動したようです。2つの間に違いはありますか?
-編集-
1つはオブジェクトへの通知用で、もう1つはスレッドへの割り込みです。しかし、これらは両方とも同じ結果につながります。つまり、このスレッドはウェイクアップされます。したがって、私が聞きたいのは、これら2つの状況の結果が互いにどのように異なるかです。
あるモニターでスレッドが通知を呼び出すと、そのモニターで待機している単一のスレッドが起動しますが、どのスレッドが起動されるかは、スケジューラーによって決定されます。(または、スレッドはnotifyAllを呼び出すことができます。これにより、そのモニターを待機しているすべてのスレッドが起動し、それらすべてがモニターを求めて競合し、敗者は待機に戻ります。そのため、呼び出しのターゲットが異なり、通知が行われます。起動するスレッドを選択するようにスケジューラに指示します。
通知とは異なり、割り込みは特定のスレッドを対象としています。また、割り込みでは、割り込みを受けたスレッドがモニターで待機している必要はありません。スレッドがモニターで待機を呼び出すには、まずそのモニターを取得してから、スレッドが待機を完了するか、割り込みが発生するまで、そのモニターを解放する必要があります。
オラクル社の推奨は、中断はキャンセルのみに使用することです。また、java.util.concurrentのクラスは、キャンセルに割り込みを使用するように設計されています。
この例では、中断はあまり効果的ではありません。制御がwhileループを離れないため、スレッドは待機中の条件をチェックする必要があり、whileループ条件には割り込みフラグが設定されているかどうかのチェックがありません。中断されたスレッドが待機状態に戻る可能性があります。
このコードが中断されると終了するのではなく、待機に戻るのではなく、中断されたフラグのステータスのチェックをループ条件に追加し、catchブロックに中断フラグを設定させます(例外がスローされるとリセットされます)。
synchronized (Foo.class) {
while (someCondition && !Thread.currentThread().isInterrupted()) {
try {
Foo.class.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加