中斷I/O操作
然而,如果執行緒在I/O操作進行時被阻塞,又會如何? I/O操作可以阻塞執行緒一段相當長的時間,特別是牽扯到網路應用時。例如,伺服器可能需要等待一個請求(request),又或者,一個網頁應用程式可能要等待遠端主機的回應。
如果你正在使用通道(channels)(這是在Java 1.4中引入的新的I/O API),那麼被阻塞的執行緒將會收到一個 ClosedByInterruptException異常。如果情況是這樣,其程式碼的邏輯和第三個例子中的是一樣的,只是異常不同而已。
但是,你可能正在使用Java1.0之前就存在的傳統的I/O,而且要求更多的工作。既然這樣,Thread.interrupt()將不起作用,因為執行緒將不會退出被阻塞狀態。 Listing 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異常被拋出非常相似。
唯一要說明的是,必須存在socket的引用(reference),只有這樣close()方法才能被呼叫。這意味著socket物件必須被共用。 Listing 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..." ); } }
以下是運行Listing E中程式碼後的輸出:
Starting thread... Waiting for connection... Asking thread to stop... accept() failed or interrupted... Thread exiting under request... Stopping application...
多執行緒是一個強大的工具,然而它正呈現出一系列難題。其中之一是如何中斷一個正在運行的執行緒。如果適當地實現,使用上述技術中斷執行緒將比使用Java平台上已經提供的內嵌操作更為簡單。
以上就是Java怎樣中斷一個運作中的執行緒(3)的內容,更多相關內容請關注PHP中文網(www.php.cn)!