一、作用
1. 什么是中断
原来对中断的理解可能是:
你:在打游戏
女朋友:别打游戏了,赶快过来吃饭
你:听到女朋友招呼之后立马中断手中的游戏乖乖过去吃饭
其实是:
在多线程中,『中断是一种协同机制』。就是女朋友叫你吃饭,你收到了中断游戏通知,但是否马上放下手中的游戏去吃饭看你心情。
2. 为什么有中断
二、概念
每个线程对象都有一个boolean
类型的标志,代表是否有中断请求,该标志通过底层 native 实现。
几个相关方法
1. Thread 的实例方法interrupt()
是唯一一个可以将中断标志设为true
的方法
线程被中断的反应是不一样的,脾气不好的直接抛出InterruptedException
这些可能阻塞的方法如果声明有
throws InterruptedExcetion
,也就是暗示我们它们是可中断的。
2. Thread 的实例方法isInterrupted()
返回当前中断标志
true
线程被中断false
线程没被中断或被清空了中断标志
3. Thread 的静态方法interrupted()
返回当前中断标志,并清空中断标志
三、使用
原则1:如果遇到的是可中断的阻塞方法, 并抛出 InterruptedException,可以继续向方法调用栈的上层抛出该异常;如果检测到中断,则可清除中断状态并抛出 InterruptedException,使当前方法也成为一个可中断的方法
原则2:若有时候不太方便在方法上抛出 InterruptedException,比如要实现的某个接口中的方法签名上没有 throws InterruptedException,这时就可以捕获可中断方法的 InterruptedException 并通过 Thread.currentThread.interrupt() 来重新设置中断状态。
1. 优雅得中断线程
捕获的
InterruptedException
并通过Thread.currentThread.interrupt()
来重新设置中断状态
public class InterruptTest {
public static void main(String[] args) {
Thread t = new PrintThread();
t.setName("PrintThread");
t.start();
try {
TimeUnit.SECONDS.sleep(5);
t.interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println(e.getMessage());
}
}
/**
* 每隔1s打印一次数据
*/
static class PrintThread extends Thread {
private volatile boolean enable = true;
public boolean isEnable() {
return enable;
}
public void setEnable(boolean enable) {
this.enable = enable;
}
@Override
public void run() {
while (enable && !isInterrupted()) {
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
System.out.println("run at " + sdf.format(new Date()));
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println(e.getMessage());
System.out
.println("PrintThread------Thread isInterrupted=" + Thread.currentThread().isInterrupted());
// 再次将中断标志设置为true
Thread.currentThread().interrupt();
System.out
.println("2--PrintThread------Thread isInterrupted=" + Thread.currentThread().isInterrupted());
}
}
}
}
}
注意:
sleep()
方法抛出 InterruptedException后,中断标识也被清空置为 false,如果在catch
没有通过调用th.interrupt()
方法再次将中断标识置为true
,会导致无限循环,中断线程不成功