1.中断概述
中断只是一种协商机制,如果要中断一个线程,需要手动调用该线程的interrupt方法,将此线程对象的中断标识设为true(默认中断标志位为false),接着我们需要手动写代码去不断的检测要中断线程的标识位,如果为true,表示别的线程请求将这条线程中断。所以说一个线程的命运是掌握在自己手中的。
2.中断的相关API——三大方法
3.面试常考题
3.1如何停止并中断运行中的线程?
-
通过volatile修饰变量来实现,volatile具有可见性,别的线程修改其共用的变量来协商中断线程。
-
使用原子类AtomicBoolean实现,也是通过别的线程修改其中的boolean类型的变量来协商中断线程。
-
通过Thread类中自带的中断API实现,利用interrupt() 和isInterrupted()方法,要求在中断的线程中需要不断的监听中断标志位的状态。
public class InterruptDemo {
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
while (true) {
if (Thread.currentThread().isInterrupted()) { //自己不断的循环判断
System.out.println(Thread.currentThread().getName() + " isInterrupted()的值被改为true,t1程序停止");
break;
}
System.out.println("-----------hello isInterrupted()");
}
}, "t1");
t1.start();
try {
TimeUnit.MILLISECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
//t2向t1放出协商,将t1中的中断标识位设为true,希望t1停下来
new Thread(() -> t1.interrupt(), "t2").start();
//当然,也可以t1自行设置
//t1.interrupt();
}
}
/**
* -----------hello isInterrupted()
* -----------hello isInterrupted()
* -----------hello isInterrupted()
* -----------hello isInterrupted()
* t1 isInterrupted()的值被改为true,t1程序停止
*/
3.2线程的中断标识为true,是不是被设置线程就立刻停止了?
并不是立刻停止,具体来说,当调用需要中断线程的Interrupt()方法时,有以下两种情况:
-
如果此线程正处于正常的活动状态,那么就会设置线程的中断标志位为true,仅此而已,线程还会继续不受影响的运行。
-
如果此线程正处于阻塞的状态(例如sleep,wait等),那么该线程将立刻退出被阻塞的状态,并且清除Interrupt的状态(设置为false),并且抛出一个InterruptedException异常。
总之,中断只是一种协商机制,修改中断标识位仅此而已,并不是立刻stop打断。
3.3静态方法Thread.interrupted(),谈谈你的理解?
此方法是一个静态方法,该方法的含义是返回此线程的中断标志位的状态,并且清空中断标识位(设置为false)。这就可能会导致连续两次调用此方法,而返回回来的结果却不一致。
3.4对于interrupted()和isInterrupted()的共同点和区别?
共同点:
-
都能返回此刻线程标志位的状态。
-
调用的都是本地(native)的isInterrupted(boolean ClearInterrupted)方法。
区别:
-
interrupted()方法是静态方法,isInterrupted()方法是实例方法。
-
interrupted()方法会清空中断标志位状态(传入参数true),而isInterrupted()方法不会(传入参数false)。