Thread#interrupt
Thread#interrupt()でスレッドに割り込みます。
- (特殊な場合をのぞき、)割り込まれると、スレッドの「割り込まれたフラグ」がtrueになります。
- スレッドで実行中の処理がキャンセル可能であれば、定期的にこのフラグをチェックして「trueならキャンセルする」といった実装を行えます。
- フラグのチェックは「Thread#interrupted」,「Thread#isInterrupted」で行えます。
- 「Thread#interrupted」の場合、実行後フラグがfalseになります。
- 「Thread#isInterrupted」はフラグの状態は変更されません。また、こちらはインスタンスメソッドです。
- 割り込まれた時、Object#wait()やThread#sleep(long)で待ち状態であった場合、InterruptedExceptionが発生します。このときスレッドの「割り込まれたフラグ」はtrueにならず、falseのままになります。
- その他、interruptible channelやSelectorも特殊な動作となるらしい。(詳細はJavaDocを参照)
サンプル
Thread t = Thread.currentThread(); System.out.println( t.isInterrupted() ); // false System.out.println( Thread.interrupted() ); // false // 割り込み! t.interrupt(); System.out.println( t.isInterrupted() ); // true System.out.println( t.isInterrupted() ); // true / 呼び出し後もフラグは変更されない System.out.println( Thread.interrupted() ); // true System.out.println( Thread.interrupted() ); // false / 呼び出し後フラグがfalseにされる。 System.out.println( "---" ); t = new Thread() { public void run() { Object o = new Object(); try { // waitで待つ synchronized( o ) { o.wait(); } } catch ( InterruptedException e ) { System.out.println( "interrupted!" ); } // wait中に割り込まれた場合、フラグは立たない。 System.out.println( Thread.currentThread().isInterrupted() ); // false System.out.println( Thread.interrupted() ); // false } }; t.start(); Thread.sleep( 1000 ); t.interrupt(); t.join();
実行結果です。
false false true true true false --- interrupted! false false