------------------------------------------------------------我是copy分割线----------------------------------------------安全
如何中止java的线程一直是一个开发多线程程序常遇到的一个问题。也有好多人问过我,因此今天在这里总结一下但愿可让更多的人知道在java中如何安全的结束一个正在运行的线程。多线程
在Java的多线程编程中,java.lang.Thread类型包含了一些列的方法start(), stop(), stop(Throwable) and suspend(), destroy() and resume()。经过这些方法,咱们能够对线程进行方便的操做,可是这些方法中,只有start()方法获得了保留。
那么,咱们究竟应该如何中止线程呢?这里咱们介绍两种方法:
1. 使用共享变量的方式
在这种方式中,之因此引入共享变量,是由于该变量能够被多个执行相同任务的线程用来做为是否中断的信号,通知中断线程的执行。
public class ThreadFlag extends Thread
{
public volatile boolean exit = false;
public void run()
{
while (!exit);
}
public static void main(String[] args) throws Exception
{
ThreadFlag thread = new ThreadFlag();
thread.start();
sleep(3000); // 主线程延迟3秒
thread.exit = true; // 终止线程thread
thread.join();
System.out.println("线程退出!");
}
}
在上面代码中定义了一个退出标志exit,当exit为true时,while循环退出,exit的默认值为false。在定义exit时,使用了一个Java关键字volatile,这个关键字的目的是使exit同步,也就是说在同一时刻只能由一个线程来修改exit的值。
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();
}
}
2. 使用interrupt方法终止线程
若是一个线程因为等待某些事件的发生而被阻塞,又该怎样中止该线程呢?这种状况常常会发生,好比当一个线程因为须要等候键盘输入而被阻塞,或者调用Thread.join()方法,或者Thread.sleep()方法,在网络中调用ServerSocket.accept()方法,或者调用了DatagramSocket.receive()方法时,都有可能致使线程阻塞,使线程处于处于不可运行状态时,即便主程序中将该线程的共享变量设置为true,但该线程此时根本没法检查循环标志,固然也就没法当即中断。这里咱们给出的建议是,不要使用stop()方法,而是使用Thread提供的interrupt()方法,由于该方法虽然不会中断一个正在运行的线程,可是它可使一个被阻塞的线程抛出一个中断异常,从而使线程提早结束阻塞状态,退出堵塞代码。
class MyThread extends Thread {
volatile boolean stop = false;
public void run() {
while (!stop) {
System.out.println(getName() + " is running");
try {
sleep(1000);
} catch (InterruptedException e) {
System.out.println("week up from blcok...");
stop = true; // 在异常处理代码中修改共享变量的状态
}
}
System.out.println(getName() + " is exiting...");
}
}
class InterruptThreadDemo3 {
public static void main(String[] args) throws InterruptedException {
MyThread m1 = new MyThread();
System.out.println("Starting thread...");
m1.start();
Thread.sleep(3000);
System.out.println("Interrupt thread...: " + m1.getName());
m1.stop = true; // 设置共享变量为true
m1.interrupt(); // 阻塞时退出阻塞状态
Thread.sleep(3000); // 主线程休眠3秒以便观察线程m1的中断状况
System.out.println("Stopping application...");
}
}
注意:在Thread类中有两个方法能够判断线程是否经过interrupt方法被终止。一个是静态的方法interrupted(),一个是非静态的方法isInterrupted(),这两个方法的区别是interrupted用来判断当前线是否被中断,而isInterrupted能够用来判断其余线程是否被中断。