如何停止java线程

简介

在Java的多线程编程中,java.lang.Thread类型包含了一些列的方法start(), stop(), stop(Throwable) and suspend(), destroy() and resume()。通过这些方法,我们可以对线 程进行方便的操作,但是这些方法中,只有start()方法得到了保留。

在Sun公司的一篇文章《Why are Thread.stop, Thread.suspend and Thread.resume Deprecated? 》中详细讲解了舍弃这些方法的原因。那么,我们究竟应该如何停止线程呢?

建议使用的方法

在《Why are Thread.stop, Thread.suspend and Thread.resume Deprecated? 》中,建 议使用如下的方法来停止线程:

private volatile Thread blinker;     public void stop() {         blinker = null;     }     public void run() {         Thread thisThread = Thread.currentThread();         while (blinker == thisThread) {             try {                 thisThread.sleep(interval);             } catch (InterruptedException e){             }             repaint();         }     }

关于使用volatile关键字的原因,请查看 http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#36930。

当线程处于非运行(Run)状态

当线程处于下面的状况时,属于非运行状态:

* 当sleep方法被调用。

*当wait方法被调用。

*当被I/O阻塞,可能是文件或者网络等等。

当线程处于上述的状态时,使用前面介绍的方法就不可用了。这个时候,我们可以使用 interrupt()来打破阻塞的情况,如:

public void stop() {         Thread tmpBlinker = blinker;         blinker = null;         if (tmpBlinker != null) {            tmpBlinker.interrupt();         }     }

当interrupt()被调用的时候,InterruptedException将被抛出,所以你可以再run方法中 捕获这个异常,让线程安全退出:

try {    ....    wait();} catch (InterruptedException iex) {    throw new RuntimeException("Interrupted",iex);}

阻塞的I/O

当线程被I/O阻塞的时候,调用interrupt()的情况是依赖与实际运行的平台的。在 Solaris和Linux平台上将会抛出InterruptedIOException的异常,但是Windows上面不会有这 种异常。所以,我们处理这种问题不能依靠于平台的实现。如:

package com.cnblogs.gpcusterimport java.net.*;import java.io.*;public abstract class InterruptibleReader extends Thread {     private Object lock = new Object( );     private InputStream is;     private boolean done;     private int buflen;     protected void processData(byte[] b, int n) { }     class ReaderClass extends Thread {         public void run( ) {             byte[] b = new byte[buflen];             while (!done) {                 try {                     int n = is.read(b, 0,  buflen);                     processData(b, n);                 } catch (IOException ioe) {                     done = true;                 }             }             synchronized(lock) {                 lock.notify( );             }         }     }     public InterruptibleReader(InputStream is) {         this(is, 512);     }     public InterruptibleReader(InputStream is, int len) {         this.is = is;         buflen = len;     }     public void run( ) {         ReaderClass rc = new ReaderClass( );         synchronized(lock) {             rc.start( );             while (!done) {                 try {                     lock.wait( );                 } catch (InterruptedException ie) {                     done = true;                     rc.interrupt( );                     try {                         is.close( );                     } catch (IOException ioe) {}                 }             }         }     }}

另外,我们也可以使用InterruptibleChannel接口。 实现了InterruptibleChannel接口 的类可以在阻塞的时候抛出ClosedByInterruptException。如:

package com.cnblogs.gpcusterimport java.io.BufferedReader;import java.io.FileDescripTor;import java.io.FileInputStream;import java.io.InputStream;import java.io.InputStreamReader;import java.nio.channels.Channels;public class InterruptInput {     static BufferedReader in = new BufferedReader(             new InputStreamReader(             Channels.newInputStream(             (new FileInputStream(FileDescripTor.in)).getChannel ())));     public static void main(String args[]) {         try {             System.out.println("Enter lines of input (user  ctrl+Z Enter to terminate):");             System.out.println("(Input thread will be  interrupted in 10 sec.)");             // interrupt input in 10 sec             (new TimeOut()).start();             String line = null;             while ((line = in.readLine()) != null) {                 System.out.println("Read  line:'"+line+"'");             }         } catch (Exception ex) {             System.out.println(ex.toString()); //  printStackTrace();         }     }     public static class TimeOut extends Thread {         int sleepTime = 10000;         Thread threadToInterrupt = null;         public TimeOut() {             // interrupt thread that creates this  TimeOut.             threadToInterrupt = Thread.currentThread();             setDaemon(true);         }         public void run() {             try {                 sleep(10000); // wait 10 sec             } catch(InterruptedException ex) {/*ignore*/}             threadToInterrupt.interrupt();         }     }}

这里还需要注意一点,当线程处于写文件的状态时,调用interrupt()不会中断线程。

请让我们从容面对这离别之后的离别。

如何停止java线程

相关文章:

你感兴趣的文章:

标签云: