interrupt()简介
interrupt():通知线程中断。(不是中断线程,只是修改中断标记置true,线程正常执行)。
具体对一个线程调用thread.interrupt()有如下情况:
- 当线程处于阻塞状态,比如wait(),sleep,join(),会抛出 InterruptedException 异常。
- 当线程处于整除状态,设置中断标志位为false,线程整除运行不受任何影响
小坑
- 当catch (InterruptedException e) {}捕获到中断异常后,会重新把标志位设置为true,导致thread.isInterrupted() 一直为false。
- 另外,当线程死亡的时候调用isInterrupted()也为false;
那如何直到查看是否线程是否中断呢,调用
thread.isInterrupted() 判断是否中断,此方法不改变中断状态。
案例实操
配合wait(),sleep,join()并抛InterruptedException 异常的方式使用
public class InterruptTest {
static volatile boolean flag=true;
public static void main(String[] args) throws IOException, InterruptedException {
CountDownLatch latch1 = new CountDownLatch(3);
CountDownLatch latch2 = new CountDownLatch(3);
Thread thread1 = new Thread(() -> {
latch1.countDown();
System.out.println("线程:" + Thread.currentThread().getName() + "开始执行");
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("线程:" + Thread.currentThread().getName() + "安全退出");
latch2.countDown();
}
}
});
thread1.start();
Object obj = new Object();
Thread thread2 = new Thread(() -> {
try {
latch1.countDown();
synchronized (obj){
System.out.println("线程:" + Thread.currentThread().getName() + "开始执行");
obj.wait(); // 注意得在同步代码块中,需要报监视器异常
}
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("线程:" + Thread.currentThread().getName() + "安全退出");
latch2.countDown();
}
});
thread2.start();
Object obj2=new Object();
Thread thread3 = new Thread(() -> {
try {
latch1.countDown();
synchronized (obj2){
System.out.println("线程:" + Thread.currentThread().getName() + "开始执行");
Thread.currentThread().join(); // 一直阻塞直到线程死亡,底层调用wait()方法进行阻塞,所以也要synchronized
}
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("线程:" + Thread.currentThread().getName() + "安全退出");
latch2.countDown();
}
});
thread3.start();
latch1.await();
System.out.println("线程:"+Thread.currentThread().getName()+":输入回车中断线程");
System.in.read();
thread1.interrupt(); // 将线程的中断状态置为false,导致抛出interrupted异常,并会重新置中断位为false
thread2.interrupt();
thread3.interrupt();
Thread thread4 = new Thread(() -> {
while (flag){}// 不能让线程终止了,当线程终止的时候isInterrupted()方法为false
});
thread4.start();
thread4.interrupt();
latch2.await();
System.out.println("线程:"+Thread.currentThread().getName()+":输入回车验证中断状态");
System.in.read();
System.out.println("thread1是否中断:"+thread1.isInterrupted()); // false 因为InterruptedException异常被捕获后中断标志又记为false
System.out.println("thread4是否中断:"+thread4.isInterrupted()); // true
flag=false;
}
}
线程终止的三种方式
一、正常结束
二、thread.stop()
非常危险,不推荐,相当于切断电源,停止run()方法接下来所有代码,包括catch,finally,会产生各种意想不到的方法
三、thread.interrupt()
总结
interrupt()改变线程的中断状态,可由当前线程或其他线程调用,当线程阻塞的时候还会抛出InterruptedException异常。可通过isInterrupted()判断线程是否中断。