中断java程序代码 java程序终止( 二 )


到目前为止一切顺利!但是 当线程等待某些事件发生而被阻塞 又会发生什么?当然 如果线程被阻塞 它便不能核查共享变量 也就不能停止 这在许多情况下会发生 例如调用Object wait() ServerSocket accept()和DatagramSocket receive()时 这里仅举出一些
他们都可能永久的阻塞线程 即使发生超时 在超时期满之前持续等待也是不可行和不适当的 所以 要使用某种机制使得线程更早地退出被阻塞的状态
很不幸运 不存在这样一种机制对所有的情况都适用 但是 根据情况不同却可以使用特定的技术 在下面的环节 我将解答一下最普遍的例子
使用Thread interrupt()中断线程
正如Listing A中所描述的 Thread interrupt()方法不会中断一个正在运行的线程 这一方法实际上完成的是 在线程受到阻塞时抛出一个中断信号 这样线程就得以退出阻塞的状态 更确切的说 如果线程被Object wait Thread join和 Thread sleep三种方法之一阻塞 那么 它将接收到一个中断异常(InterruptedException) 从而提早地终结被阻塞状态
因此 如果线程被上述几种方法阻塞 正确的停止线程方式是设置共享变量 并调用interrupt()(注意变量应该先设置) 如果线程没有被阻塞 这时调用interrupt()将不起作用 否则 线程就将得到异常(该线程必须事先预备好处理此状况) 接着逃离阻塞状态 在任何一种情况中 最后线程都将检查共享变量然后再停止 Listing C这个示例描述了该技术
Listing Cclass Exampleextends Thread {volatile boolean stop = false;public static void main( String args[] ) throws Exception {Examplethread = new Example ();System out println(Starting thread);thread start();Thread sleep();System out println(Asking thread to stop);thread stop = true;//如果线程阻塞 将不会检查此变量thread interrupt();Thread sleep();System out println(Stopping application);//System exit();}public void run() {while ( !stop ) {System out println(Thread running);try {Thread sleep();} catch ( InterruptedException e ) {System out println(Thread interrupted);}}System out println(Thread exiting under request);}}
一旦Listing C中的Thread interrupt()被调用 线程便收到一个异常 于是逃离了阻塞状态并确定应该停止 运行以上代码将得到下面的输出
Starting thread Thread running Thread running Thread running Asking thread to stop Thread interrupted Thread exiting under request Stopping application
中断I/O操作
然而 如果线程在I/O操作进行时被阻塞 又会如何?I/O操作可以阻塞线程一段相当长的时间 特别是牵扯到网络应用时 例如 服务器可能需要等待一个请求(request) 又或者 一个网络应用程序可能要等待远端主机的响应
如果你正使用通道(channels)(这是在Java 中引入的新的I/O API) 那么被阻塞的线程将收到一个 ClosedByInterruptException异常 如果情况是这样 其代码的逻辑和第三个例子中的是一样的 只是异常不同而已
但是 你可能正使用Java 之前就存在的传统的I/O 而且要求更多的工作 既然这样 Thread interrupt()将不起作用 因为线程将不会退出被阻塞状态 Listing D描述了这一行为 尽管interrupt()被调用 线程也不会退出被阻塞状态
Listing Dimport java io *;class Exampleextends Thread {public static void main( String args[] ) throws Exception {Examplethread = new Example ();System out println(Starting thread);thread start();Thread sleep();System out println(Interrupting thread);thread interrupt();Thread sleep();System out println(Stopping application);//System exit();}public void run() {ServerSocket socket;try {socket = new ServerSocket( );} 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);}}}}

推荐阅读