I/O 操作の中断
ただし、I/O 操作の進行中にスレッドがブロックされた場合はどうなるのでしょうか? I/O 操作は、特にネットワーク アプリケーションが関与している場合に、スレッドをかなりの時間ブロックする可能性があります。たとえば、サーバーがリクエストを待つ必要がある場合や、ネットワーク アプリケーションがリモート ホストからの応答を待つ必要がある場合があります。
チャネル (これは Java 1.4 で導入された新しい I/O API) を使用している場合、ブロックされたスレッドは ClosedByInterruptException 例外を受け取ります。この場合、コードのロジックは 3 番目の例と同じですが、例外が異なるだけです。
ただし、Java 1.0 より前に存在し、より多くの作業が必要な従来の I/O を使用している可能性があります。この場合、スレッドはブロック状態から抜け出せないため、Thread.interrupt() は機能しません。リスト D はこの動作を説明しています。 interrupt() が呼び出されても、スレッドはブロック状態から抜け出しません。
Listing D import java.io.*; class Example4 extends Thread { public static void main( String args[] ) throws Exception { Example4 thread = new Example4(); System.out.println( "Starting thread..." ); thread.start(); Thread.sleep( 3000 ); System.out.println( "Interrupting thread..." ); thread.interrupt(); Thread.sleep( 3000 ); System.out.println( "Stopping application..." ); //System.exit( 0 ); } public void run() { ServerSocket socket; try { socket = new ServerSocket(7856); } catch ( IOException e ) { System.out.println( "Could not create the socket..." ); return; } while ( true ) { System.out.println( "Waiting for connection..." ); try { Socket sock = socket.accept(); } catch ( IOException e ) { System.out.println( "accept() failed or interrupted..." ); } } } }
幸いなことに、Java プラットフォームは、スレッドをブロックしているソケットの close() メソッドを呼び出すという、この状況に対する解決策を提供しています。この場合、スレッドが I/O 操作によってブロックされると、スレッドは SocketException を受け取ります。これは、interrupt() メソッドを使用して InterruptedException をスローするのと非常によく似ています。
唯一注意すべきことは、ソケットへの参照が存在する必要があり、その場合にのみ close() メソッドを呼び出すことができるということです。これは、ソケット オブジェクトを共有する必要があることを意味します。リスト E はこの状況を説明しています。実行ロジックは前の例と同じです。
Listing E import java.net.*; import java.io.*; class Example5 extends Thread { volatile boolean stop = false; volatile ServerSocket socket; public static void main( String args[] ) throws Exception { Example5 thread = new Example5(); System.out.println( "Starting thread..." ); thread.start(); Thread.sleep( 3000 ); System.out.println( "Asking thread to stop..." ); thread.stop = true; thread.socket.close(); Thread.sleep( 3000 ); System.out.println( "Stopping application..." ); //System.exit( 0 ); } public void run() { try { socket = new ServerSocket(7856); } catch ( IOException e ) { System.out.println( "Could not create the socket..." ); return; } while ( !stop ) { System.out.println( "Waiting for connection..." ); try { Socket sock = socket.accept(); } catch ( IOException e ) { System.out.println( "accept() failed or interrupted..." ); } } System.out.println( "Thread exiting under request..." ); } }
リスト E のコードを実行した後の出力は次のとおりです。
Starting thread... Waiting for connection... Asking thread to stop... accept() failed or interrupted... Thread exiting under request... Stopping application...
マルチスレッドは強力なツールですが、それ自体に一連の困難があります。その 1 つは、実行中のスレッドを中断する方法です。適切に実装されていれば、上記の手法を使用してスレッドを中断することは、Java プラットフォームですでに提供されているインライン操作を使用するよりも簡単です。
上記は、Java で実行中のスレッドを中断する方法 (3) の内容です。その他の関連コンテンツについては、PHP 中国語 Web サイト (www.php.cn) に注目してください。