Thread.run执行完毕,线程就结束了;
Thread.stop:虽然确实可以停止一个正在运行的线程,但是这种方法是不安全的,也不被提倡;
Thread.interrupt:并不会中断一个正在运行的线程
中断线程最好的,最受推荐的方式是使用共享变量发出信号,告诉线程必须停止当前任务,而线程需要周期性地检查这一变量,然后有秩序地终止任务(没有用到interrupt方法,共享变量是volatile类型或将对它的一切访问封装到同步块/方法中);
但是,当线程因等待某些事件发生而被阻塞,便不能核查共享变量,也就不能停止,所以需要某种机制使得线程更早地退出被阻塞的状态。
Thread.interrupt实际完成的是,在线程受到阻塞时抛出一个中断信号,这样线程就可以退出阻塞状态,更确切地说,如果线程被Object.wait,Thread.join和Thread.sleep三种方法之一阻塞,就会接到一个InterruptedException,从而提早结束阻塞状态。
因此,如果线程被上述几种方式阻塞,正确的停止方式是:先设置共享变量,再调用interrupt方法,如果线程没有被阻塞,这时interrupt将不起作用;否则,线程将得到异常,并逃离阻塞状态。
代码示例:
public class Test {
public static void main(String[] args) throws InterruptedException {
MyThread t = new MyThread();
System.out.println("Start thread...");
t.start();
Thread.sleep(3000);
System.out.println("Ask thread to stop...");
t.stop = true;
t.interrupt();
Thread.sleep(3000);
System.out.println("stop...");
}
static class MyThread extends Thread {
static volatile boolean stop = false;
public void run() {
while(!stop) {
try {
Thread.sleep(1000);
System.out.println("MyThread running...");
} catch (InterruptedException e) {
System.out.println("MyThread interrupted...");
}
}
System.out.println("MyThread exist under request...");
}
}
}
运行结果:
Start thread...
MyThread running...
MyThread running...
Ask thread to stop...
MyThread interrupted...
MyThread exist under request...
stop...
中断I/O操作:
I/O操作可以阻塞线程一段相当长的时间,特别是牵扯到网络应用时。例如,服务器可能要等待一个请求(request),又或者,一个网络应用程序可能要等待 远端主机的响应。
如果正在使用通道(channels,在Java4中引入的I/O API),那么被阻塞的线程将收到一个ClosedByInterruptException异常,如果情况是这样,代码逻辑和上面的代码是相同的,只不过异常不同;
但是,如果使用的是Java 1.0之前的传统I/O,Thread.interrupt将不起作用,因为线程将不会退出被阻塞的状态。此时,Java平台的解决方案为:调用阻塞该线程的套接字Socket的close方法,在这种情形下,如果线程被I/O操作阻塞,该线程将接收一个SocketException,这与interrupt方法引起的InterruptedException异常非常相似。唯一要说明的是,必须存在socket的引用,只有这样close方法才能被调用,这意味着socket对象必须被共享。