相关文章:
这里我们再来了解下 interrupt() 方法的使用
一、举例说明
public class InterruptDemo {
public static void main(String[] args) throws InterruptedException {
Runnable interruptTask = () -> {
int i = 0;
try {
// 在正常运行任务时,经常检查本线程的中断标志位,如果被设置了中断标志就自行停止线程
while (!Thread.currentThread().isInterrupted()) {
// 休眠100ms
Thread.sleep(100);
i++;
System.out.println(Thread.currentThread().getName()
+ " (" + Thread.currentThread().getState() + ") loop " + i);
}
} catch (InterruptedException e) {
// 在调用阻塞方法时正确处理InterruptedException异常 (例如:catch异常后就结束线程)
System.out.println(Thread.currentThread().getName()
+ " (" + Thread.currentThread().getState() + ") catch InterruptedException.");
}
};
Thread t1 = new Thread(interruptTask, "t1");
System.out.println(t1.getName() +" ("+t1.getState()+") is new.");
// 启动线程t1
t1.start();
System.out.println(t1.getName() +" ("+t1.getState()+") is started.");
// 主线程休眠250ms,然后主线程给t1发“中断”指令。
Thread.sleep(250);
t1.interrupt();
System.out.println(t1.getName() +" ("+t1.getState()+") is interrupted.");
// 主线程休眠300ms,然后查看t1的状态。
Thread.sleep(300);
System.out.println(t1.getName() +" ("+t1.getState()+") is interrupted now.");
}
}
// t1 (NEW) is new.
// t1 (RUNNABLE) is started.
// t1 (RUNNABLE) loop 1
// t1 (RUNNABLE) loop 2
// t1 (TIMED_WAITING) is interrupted.
// t1 (RUNNABLE) catch InterruptedException.
// t1 (TERMINATED) is interrupted now.
-
如上所示,我们先创建了一个线程 t1,此时线程状态为 NEW
-
接着调用 start() 方法启动线程 t1,此时线程状态为 RUNNABLE,同时让主线程休眠 300 ms
-
此时线程 t1 正在执行 run() 方法中的业务逻辑,每休眠 100 ms 打印一次,此时线程状态为 RUNNABLE
-
当线程 t1 处于第三次休眠的时候,主线程结束休眠,然后调用 interrupt() 方法通知线程 t1 要进行中断了,并将中断标识设为 true,此时线程 t1 处于阻塞状态,线程状态为 TIMED_WAITING
-
由于检测到中断标识为 true,t1 立刻退出了阻塞状态,并抛出 InterruptedException 异常,此时线程状态为 RUNNABLE
-
然后让主线程再休眠 300 ms,休眠结束后打印 t1 的状态,此时线程状态为 TERMINATED
二、归纳总结
-
当调用 interrupt() 方法时,如果线程处于阻塞状态,那么线程将立刻退出阻塞状态,并抛出 InterruptedException 异常
-
当调用 interrupt() 方法时,如果线程处于正常活动状态,那么会将该线程的中断标志设为 true,被设置了中断标志的线程会继续执行,不受影响,线程何时中断取决于线程本身