如何中止JAVA线程

如何中止JAVA线程

如何中止java的线程一直是一个困恼咱们开发多线程程序的一个问题。这个问题最终在Java5的java.util.concurrent中获得了回答:使用interrupt(),让线程在run方法中中止。html

简介

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

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

建议使用的方法

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

    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方法被调用。ide

  • 当wait方法被调用。post

  • 当被I/O阻塞,多是文件或者网络等等。ui

当线程处于上述的状态时,使用前面介绍的方法就不可用了。这个时候,咱们能够使用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.gpcuster

import 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.gpcuster

import 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()不会中断线程。


 


相关文章
相关标签/搜索