interrupt(): 打断 sleep、wait、join 的线程会抛出 InterruptedException 异常并清除打断标记,如果打断正在运行的线程、park 的线程则会重新设置打断标记
isInterrupted(): 不会清除打断标记
interrupted(): 会清除打断标记
一、调用 interrupt() 方法中断正在运行的线程
@Slf4j public class InterruptDemo { public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(() -> { while (true) { } }); t1.start(); // 先让 t1 线程运行 TimeUnit.SECONDS.sleep(1); // isInterrupted() 可以获取到线程的打断标记,如果线程被打断,则打断标记为 true,并且该方法不会清除打断标记 log.info("before interrupt status >>> {}", t1.isInterrupted()); // 打断正在运行的线程/park 状态的线程会重新设置打断标记,打断 sleep、join、wait 状态的线程会抛出 InterruptedException 异常,并且会清除打断标记 t1.interrupt(); log.info("after interrupt status >>> {}", t1.isInterrupted()); } }
中断正在运行的线程时,线程的中断状态变成 true,线程正常运行,并不会停止下来
调用 interrupt() 方法中断处于 sleep、wait、join 状态的线程
@Slf4j public class InterruptDemo { public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(() -> { try { // t1 线程休眠 1000s TimeUnit.SECONDS.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); log.info("{} 线程被打断了", Thread.currentThread().getName()); } }, "t1"); t1.start(); // 主线程休眠 2s,让 t1 线程有足够的时间进入 sleep 状态 TimeUnit.SECONDS.sleep(2); log.info("before interrupt status >>> {}", t1.isInterrupted()); t1.interrupt(); // 主线程休眠 2s,让 t1 线程有足够的时间进行 interrupt 操作 TimeUnit.SECONDS.sleep(2); log.info("after interrupt status >>> {}", t1.isInterrupted()); } }
中断处于 sleep、join、wait 状态的线程会抛出异常,并且会将中断状态重置为 false
中断时线程的状态 | 中断后线程的中断标记 | 中断后线程运行情况 |
正常运行的线程 | false -> true | 线程正常运行 |
sleep、wait、join 状态的线程 | false -> true -> false | 线程抛出异常,中止运行 |
然后再看一下 isInterrupted 和 interrupted 的区别
先看一下 isInterrupted() 方法源码
public boolean isInterrupted() { // ClearInterrupted 参数的含义是否清除打断标记 // false 代表不清除,打断之后 false -> true // true 代表清除,打断之后会重置打断标记 false -> true -> false return isInterrupted(false); } private native boolean isInterrupted(boolean ClearInterrupted);
接着再看一下 interrupted() 方法源码
public static boolean interrupted() { return currentThread().isInterrupted(true); } private native boolean isInterrupted(boolean ClearInterrupted);
从上面的源码中可以看出 isInterrupted() 方法和 interrupted() 方法实际上底层都是调用 private native boolean isInterrupted(boolean ClearInterrupted) 方法,唯一的区别就是传递的参数,一个是 false,一个是 true,也就是一个不会清除打断标记,另外一个会清除打断标记
线程调用 interrupt() 方法并不会真正中断线程,而是让线程具有响应中断的能力,如果你可以在 main 线程中随意的去停止 t1 线程,而 t1 线程却毫无察觉,这不是一件很可怕的事情吗,真正中断的操作应该由 t1 线程去决定,而不是 main 线程,常用的做法是在 t1 线程中根据打断标记去执行不同的逻辑
标签:标记,interrupted,t1,isInterrupted,线程,打断,interrupt From: https://www.cnblogs.com/xiaomaomao/p/17231206.html