Javaの InterruptedException に関して興味深い質問と回答があります。たとえば、 InterruptedExceptionの原因 および JavaでのInterruptedExceptionの処理 です。ただし、InterruptedExceptionの考えられる原因についてはどれも教えてくれません。
SIGTERM、SIGQUIT、SIGINTなどのOSシグナルはどうですか?コマンドラインでCTRL-Cを押すと、InterruptedExceptionが発生しますか?ほかに何か?
リストしたものはどれもInterruptedException
を生成しません。
スレッドを中断できるのは、 Thread#interrupt()
の呼び出しだけです。 JLSは、この問題について比較的明確です セクション17.2. :
17.2.3中断
中断アクションは、
Thread.interrupt
の呼び出し、およびThreadGroup.interrupt
などのそれを順番に呼び出すように定義されたメソッドで発生します。
詳細については、 割り込みに関する公式チュートリアル を参照してください。具体的には:
スレッドは、割り込み対象のスレッドに対して
interrupt
オブジェクトでThread
を呼び出すことにより、割り込みを送信します。割り込みメカニズムが正しく機能するためには、割り込みスレッドがそれ自体の割り込みをサポートしている必要があります。.。
割り込みメカニズムは、割り込みステータスと呼ばれる内部フラグを使用して実装されます。
Thread.interrupt
を呼び出すと、このフラグが設定されます。スレッドが静的メソッドThread.interrupted
を呼び出して割り込みをチェックすると、割り込みステータスがクリアされます。あるスレッドが別のスレッドの割り込みステータスを照会するために使用する非静的isInterrupted
メソッドは、割り込みステータスフラグを変更しません。慣例により、
InterruptedException
をスローして終了するメソッドは、割り込みステータスをクリアします。ただし、interrupt
を呼び出す別のスレッドによって、割り込みステータスがすぐに再設定される可能性は常にあります。
これは、他の未知の外部イベントによってトリガーされるのではなく、interrupt()
を呼び出すことによってのみ設定可能な明示的なフラグであることを意味します。これは、例外をスローするさまざまなメソッドでの例外の説明によってさらに暗示されます。 たとえば (私の強調):
InterruptedException
-スレッドが現在のスレッドを中断した場合。この例外がスローされると、現在のスレッドの割り込みステータスがクリアされます。
一般に、割り込みシステムの目的は、スレッドが他のスレッドのタスク(時間のかかる可能性のあるタスク)を中断できるようにするための、共通の明確に定義されたフレームワークを提供することです。独自のアプリケーションで明示的なロジックを使用して同様の機能を実装できますが、この明確に定義されたメカニズムを使用すると、独立したクラス(JDK、他のサードパーティコード、独自のコード内の他の独立したクラスなど)が一貫した方法でこの機能を提供できます。 。
InterruptedException
の処理について表示される多くのメモや「警告」は、完全に自発的にスローできることを意味するものではなく、未知のコンテキストで使用できる適切に設計されたオブジェクトを奨励することを目的としています。それでも、interrupt()
が機能すると推定される場合(実際には、do将来の状況で堅牢になる再利用可能なオブジェクトを作成している場合、それらが自発的にスローされる可能性があると想定したい-つまり割り込みが機能することを期待している誰かがあなたのコードをいつか使用しないという保証はありません)。
迅速な1回限りのプロジェクトの場合、本当にinterrupt()
を呼び出しておらず、呼び出していないことが確実である限り、これらの例外の特別な処理について心配する必要はありません。 interrupt()
を呼び出すことができるものを呼び出しますが、特に他のコンテキストでそのコードを再利用することになった場合は、長期的にはその影響に注意してください。