文章目录
线程中断
线程中断,如果说创建线程,启动线程,控制线程的生!那么中断线程就是控制线程的死!线程的生死大权在手,还怕掌控不了它们?
1.JDK提供的API
JDK本身为我们提供了,两套线程中断的方法。第一套让JVM直接杀死线程,第二套程序员自己来掌握线程的中断。
1.1 JVM直接中断线程
thread.stop(); // 这是一个成员方法,非静态的。
这个API,现在已经弃用,慎用,会挨骂。
1.2 程序员自己来掌握线程的中断
// 线程有一个中断状态,默认为fale,表示不需要被中断,true,表示需要被中断
thread.interrupt(); // 设置线程的中断的状态为 true。无返回值。成员方法
thread.isInterrupted(); // 获取当前线程的中断状态。成员方法
Thread.interrupted();// 获取当前线程的中断状态,并且改为false。静态方法
- 这三种API,interrupt,isInterrupted 还好理解。当使用interrupt是某个线程中断,在线程执行的代码中,判断isInterrupted的值,进行中断行为就行。
- interrupted 这个API,就有点绕的意思,但是假设一种场景,通过interrupt设置了某个线程的中断状态,但是又不想中断,只需要做一些事情。这个时候,就可以用interrupted进行判断,做完判断以后,线程的中断状态就被设置为true。一定程度上,属于扩展功能。
2.线程不同状态的影响
线程是分为NEW,RUNNABLE,BLOCKED,WAITING,TIMED_WAITING,TERMINATED 六中状态。看一下中断对六中状态的影响。
2.1 NEW | TERMINATED 无效
线程的新建和线程的中断,这两个过程有一个共同点,线程没有执行任何代码。
public class NEWOrTERMINATED {
public static void main(String[] args) throws InterruptedException {
// NEW
Thread newThread = new Thread();
System.out.println(newThread.getState()); // 获取线程的状态
newThread.interrupt(); // 设置中断信号
System.out.println(newThread.isInterrupted()); // 判断中断信号
System.out.println("-----------------------");
// TERMINATED
Thread terminatedThread = new Thread(() -> {
System.out.println("线程执行完毕");
});
terminatedThread.start(); // 启动线程
Thread.sleep(1000);
System.out.println(terminatedThread.getState()); // 获取线程的状态
terminatedThread.interrupt(); // 设置线程的中断信号
System.out.println(terminatedThread.isInterrupted()); // 判断线程的中断信号
}
}
执行结果:
可以发现,线程在此两张状态下,中断是无效。理解起来,也比较简单,线程还没有跑或着线程已经死了,这个时候,线程中断没有任何意义。
2.2 RUNNABLE 有效
线程正在运行状态。
public class RUNNABLE {
public static void main(String[] args) {
Thread runnableThread = new Thread(() -> {
while (true){
// doSomething
}
});
runnableThread.start(); // 启动线程
System.out.println(runnableThread.getState()); // 获取线程状态
runnableThread.interrupt(); // 设置中断信号
System.out.println(runnableThread.isInterrupted());// 查询线程的中断状态
}
}
结果如下:
此处说明,线程中断信号对运行中的线程是有效的。
2.3 BLOCKED 有效
线程抢锁失败。
public class BLOCKED {
private static final Object lock = new Object();
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(() -> { // 此线程是获取锁
synchronized (lock) {
while (true){
}
}
});
Thread blockedThread = new Thread(() -> { // 此线程被阻塞
synchronized (lock) {
while (true){
}
}
});
thread.start();// 先启动线程thread
Thread.sleep(1000);// 此处睡眠一秒再启动blockedThread,为了保证thread获取锁。
blockedThread.start();// 启动线程blockedThread
Thread.sleep(1000); // 此处睡眠一秒,是让blockedThread进入阻塞状态。因为线程回去抢锁,抢锁的过程不属于阻塞状态。
System.out.println(blockedThread.getState()); // 输出blockedThread线程的状态
blockedThread.interrupt(); // 设置线程blockedThread的中断信号
System.out.println(blockedThread.isInterrupted());// 查询blockedThread线程的中断信号
}
}
结果如下:
此出说明,中断信号,线程BLOCKED状态是有效的。
2.4 WAITING/TIMED_WAITING 有效且通过抛出异常来结束等待
线程处于等待状态
public class WAITINGOrTIMED_WAITING {
public static void main(String[] args) throws InterruptedException {
Thread waitingThread = new Thread(new WaitRunable());
waitingThread.start();
Thread.sleep(1000); // 保证线程waitingThread进入阻塞状态
System.out.println(waitingThread.getState()); // 获取线程的状态
waitingThread.interrupt(); // 发送中断信号
System.out.println(waitingThread.isInterrupted()); // 判断中断信号
}
static class WaitRunable implements Runnable{
@Override
public void run() {
synchronized (this){
try {
wait();
} catch (InterruptedException e) {
System.out.println("i am waiting but facing interruptexception now");
}
}
}
}
}
结果如下:
可以看出来,WAITING/TIMED_WAITING 状态的线程,会结束等待,然后抛出异常。