中断线程
在Java核心技术中,对于Interrupt是这样解释的:当对一个线程调用interrupt方法时,线程的中断状态被置位。这是每一个线程都有的boolean标志。每个线程都应该不时地检查这个标志,以判断线程是否被中断。
有两种方法:Interrupted和isInterrupted,在api文档中可以查到:
public static boolean interrupted() :这是一个静态方法,如果线程被中断,则返回true,否则返回false。
解释如下:
Tests whether the current thread has been interrupted. The interrupted status of the thread is cleared by this method.
也就是说,该方法会return线程的中断状态,然后清除它的中断状态。如果调用两次interrupted(),那么第二次会返回false而不是true,但是如果该线程在第一次调用interrupted()之后,在第二次调用interrupted()之前再次被interrupt,那么第二次调用的interrupted()就会返回true。public boolean isInterrupted():这是一个实例方法,如果线程被中断,则返回true,否则返回false。
解释如下:
Tests whether this thread has been interrupted. The interrupted status of the thread is unaffected by this method
调用isInterrupted()方法只是用来判断当前线程是否被中断,不会影响线程中断状态。
如果线程被阻塞,就无法检测中断状态。当一个被阻塞的线程(调用sleep或wait)上调用interrupt方法时,阻塞调用将会被Interrupted Exception异常中断。
如果在每次工作迭代之后都调用sleep方法(或其他可中断方法),isInterrupted检测就毫无意义了。如果在中断状态被置位时调用sleep方法,它不会休眠,相反,它会清除这一状态,并抛出InterruptedException。
public class WrongWayStopThread extends Thread{
public static void main(String[] args) {
Thread t = new WrongWayStopThread();
System.out.println("Thread is start");
t.start();
//让线程t运行一会
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//中断该线程
System.out.println("Thread is interrrupted...");
t.interrupt();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("application is stopped...");
}
@Override
public void run() {
while (!this.isInterrupted()) {
System.out.println("Thread is running...");
long time = System.currentTimeMillis();
//给一定的时间间隔再打印输出
while (System.currentTimeMillis()-time<1000) {
}
}
}
}
输出如下:
Thread is start
Thread is running…
Thread is running…
Thread is running…
Thread is interrrupted…
application is stopped…
但是如果采用sleep让线程打印输出有时间间隔,就会出现问题,程序不能正常停止,在主程序application stop之后,线程还是一直在运行:
public class WrongWayStopThread extends Thread{
public static void main(String[] args) {
Thread t = new WrongWayStopThread();
System.out.println("Thread is start");
t.start();
//让线程t运行一会
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//中断该线程
System.out.println("Thread is interrrupted...");
t.interrupt();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("application is stopped...");
}
@Override
public void run() {
while (!this.isInterrupted()) {
System.out.println("Thread is running...");
/*
* 这样做会使interrupt的status被清除,线程不能正确停止
*/
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
输出结果:
Thread is start
Thread is running…
Thread is running…
Thread is running…
Thread is running…
Thread is interrrupted…
java.lang.InterruptedException: sleep interruptedThread is running…
at java.lang.Thread.sleep(Native Method)
at com.imooc.concurrent.stop.WrongWayStopThread.run(WrongWayStopThread.java:42)
Thread is running…
Thread is running…
application is stopped…
Thread is running…
Thread is running…
Thread is running…
.
.
.