目录
一、线程中断
当我们启动一个任务或者一个线程之后,有时候时候需要任务结束之前,取消任务。像用户点击某个功能按钮后,点取消操作。但是Java
中没有提供安全的中断机制,(如:Thread.stop其实是并不推荐的)。但是Java中有一种叫 中断
的协作机制,可以使得一个线程中断另外一个线程的工作。
其实也就A线程给B线程发送一个中断的信号,至于是否会中断就要看B线程对于中断的处理结果了
二、中断方法
上面提到线程中断是一种协作机制,线程可以通过特定的API来通知另外一个线程,那么如何知道线程已经接受到中断信息呢?其实每个线程都有一个中断状态。当线程被中断时,该状态就会设置成true
。
2.1 interrupt()
该方法用于中断目标线程
Thread thread = new Thread(() -> {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("被中断---提前返回");
});
thread.start();
Thread.sleep(2000);
//调用线程的中断方法
thread.interrupt();
System.out.println("执行中断");
}
注意:Thread.sleep 和Object.wait等,都会检查中断并且及时返回处理。1.清除中断操作 2.抛出InterruptedException。
执行中断
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at thread.ThreadInterrupt.lambda$main$0(ThreadInterrupt.java:12)
at thread.ThreadInterrupt$$Lambda$1/1607521710.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)
被中断---提前返回
上面提到,sleep被中断后会回复中断状态;那么如果知道thread
线程是否被清除中断了呢,这个时候也就需要知道中断状态利用isInterrupted()
2.2 isInterrupted()
判断目标线程的中断状态
public class ThreadInterrupt1 {
public static void main(String[] args) throws Exception{
Thread thread = new Thread(() -> {
for (int i =1; i<=10000; i++) {
System.out.println(i);
}
});
thread.start();
System.out.println("线程thread的中断状态1"+thread.isInterrupted());
thread.interrupt();
System.out.println("执行中断");
System.out.println("线程thread的中断状态2"+thread.isInterrupted());
Thread.currentThread().join();
}
}
线程thread的中断状态1false
执行中断
线程thread的中断状态2true
1
2
3
4
2.3 interrupted()
清除当前中断状态,并且返回之前断值
public class ThreadInterrupt2 {
public static void main(String[] args) throws Exception{
Thread thread = new Thread(() -> {
System.out.println("do something");
});
thread.start();
Thread.currentThread().join(1000);
System.out.println("thread执行中断");
thread.interrupt();
System.out.println("清除中断状态interrupted()"+ Thread.interrupted());
}
}
执行结果:
do something
thread执行中断
清除中断状态interrupted()false
对于这个结果是不是有疑问? 按理来说是返回上一次到中断状态 应该得到到结果是true。 其实是因为interrupted()
的作用对象是当前线程,因为当前线程是main。所以返回的是当下线程的中断状态,所以也就是false
了。
3、小结
- 线程中断并不是意味这立即终止目标线程正在进行的工作,而是传递请求中断的消息。
- wait 、sleep、join都处理了中断请求。(会抛出异常、并且清除中断)
- 当我们代码中接受到中断请求,有两种处理方式:a.异常传递 b.恢复中断(使得其他断机制能都对它进行处理)