大可制作:QQ群:31564239(asp|jsp|php|mysql)

Java Gossip: 线程的停止

如果您想要停止一个线程的执行,当您查看API时,您会发现Thread的stop()方法已经被标示为 "deprecated",使用这个方法来停止一个线程是不被建议的。

请见:Why Are Thread.stop, Thread.suspend, Thread.resume and Runtime.runFinalizersOnExit Deprecated? 

如果您想要停止一个线程,您最好自行实现。

一个线程要进入Dead状态,就是执行完run()方法,简单的说,如果您想要停止一个线程的执行,就要提供一个方式让线程可以执行完run(),而这也是您自行实现线程停止的基本概念。

例如,如果线程的run()方法中执行的是一个重复执行的循环,您可以提供一个flag来控制循环是否执行,藉此让循环有可能终止、线程可以离开 run()方法以终止线程:
public class SomeThread implements Runnable {
    private boolean isContinue = true;

    public void terminate() {
        isContinue = false;
    }

    public void run() {
        while(isContinue) {
            // ... some statements
        }
    }
}

如果线程因为执行sleep()或是wait()而进入Not Runnable状态,而您想要停止它,您可以使用interrupt(),而程序会丢出InterruptedException异常,因而使得线程 离开run()方法,例如:

  • SomeThread.java
package onlyfun.caterpillar;

public class SomeThread implements Runnable {
public void run() {
System.out.println("sleep....going to not runnable");
try {
Thread.sleep(9999);
}
catch(InterruptedException e) {
System.out.println("I am interrupted....");
}
}
}

  • Main.java
package onlyfun.caterpillar;

public class Main {
public static void main(String[] args) {
Thread thread = new Thread(new SomeThread());
thread.start();
thread.interrupt();
}
}

如果程序因为I/O而停滞,进入Not Runnable状态,基本上您必须等待I/O完成才能离开Not Runnable,您无法使用interrupt()来使得线程离开run()方法,您要提供替代的方法,基本上的概念也是引发一个异常,而这个异常要 如何引发,要看您所使用的I/O而定,例如您使用readLine()在等待网路上的一个讯息,此时线程进入Not Runnable直到读到一个讯息,您要让它离开run()的方法就是使用close()关闭它的串流,这时会引发一个IOException异常而使得 线程离开run()方法,例如:
public class Client implements Runnable {
    private Socket skt;
    // .....

    public void terminate() {
        skt.close();
    }

    public void run() {
        // .....
       
        try {
            BufferedReader buf = new BufferedReader(
               new InputStreamReader(skt.getInputStream()));

            // 读取客户端讯息
            // 执行readLine()会进入Not runnable状态
            // 直到读到客户端讯息
            while((userMessage = buf.readLine()) != null) {
               // ....
            }
        }
        catch(IOException e) {
            System.out.println("线程被终止.......");
        }
    }
}

上面这个程序是个简单的架构示范,实际的设计必须视您的程序功能与I/O类型而定。

除了stop()之外,suspend()、resume()方法也被标示为"deprecated",这些方法如果您要达成相同的功能,您都必须自行实现,在将来新的Java版本中如果这些功能被实现,它也可能是新的接口,而不是使用现有的方法。

有关于线程的终止,还可以引用 Two-phase Termination 模式