本文内容大多基于官方文档和网上前辈经验总结,经过个人实践加以整理积累,仅供参考。
Java 使用 java.lang.Thread 实例对象的 interrupt() 方法中断某一线程
public static void main(String[] args) {
Thread thread = Thread.currentThread();
System.out.println("Ready to interrupt");
thread.interrupt();
System.out.println("Already interrupt");
}
运行结果:
从运行结果看不出任何线程已经被中断的迹象,这是因为使用 interrupt() 方法中断线程实际上只是在目标线程中设置了一个标志,表示此线程已被中断,但是线程实际并未中断,还会继续执行下去。
Java 使用 java.lang.Thread 实例对象的 isInterrupted() 方法判断中断状态。修改上面的测试代码:
public static void main(String[] args) {
Thread thread = Thread.currentThread();
System.out.println(thread.isInterrupted());
System.out.println("Ready to interrupt");
thread.interrupt();
System.out.println("Already interrupt");
System.out.println(thread.isInterrupted());
}
运行结果:
从运行结果可以看出,调用的 Thread 实例对象的 isInterrupted() 方法后,目标线程的中断状态从 false 变成了 true。
也可以通过调用 Thread 的静态方法 interrupted() 判断中断状态,因为是静态方法,所以只能判断调用此方法的线程的中断状态。与实例方法 isInterrupted() 的不同之处在于:Thread 的静态方法 interrupted() 将自动重置中断状态。
public static void main(String[] args) {
Thread thread = Thread.currentThread();
System.out.println(Thread.interrupted());
System.out.println("Ready to interrupt");
thread.interrupt();
System.out.println("Already interrupt");
System.out.println(Thread.interrupted());
System.out.println(Thread.interrupted());
}
运行结果:
从运行结果可以看出,在中断线程后第一次调用 Thread.currentThread() 打印出的线程中断状态是 true,再次调用此方法会自动重置中断状态,打印 false
中断线程的使用场景示例
class InterruptThread implements Runnable {
@Override
public void run() {
System.out.println("Ready to sleep");
try {
Thread.sleep(30000);
System.out.println("Woke up");
} catch (InterruptedException e) {
System.out.println("Interrupt sleeping");
e.printStackTrace();
return;
}
System.out.println("Interrupt thread ended");
}
}
public static void main(String[] args) throws InterruptedException {
Thread interruptTread = new Thread(new InterruptThread());
interruptTread.start();
Thread.sleep(5000);
System.out.println("Main Thread interrupt other interruptTread");
interruptTread.interrupt();
System.out.println("Main thread ended");
}
运行结果:
从运行结果可以看出,在 InterruptThread 线程实例进入休眠后,主线程调用了其 interrupt() 方法,InterruptThread 线程捕捉到异常 InterruptedException 后打印异常相关信息并返回,并未执行 System.out.println("Interrupt thread ended")
,如果不返回则会执行。
待决中断
以上示例是在线程进入休眠后调用其 interrupt() 方法执行中断操作,如果在线程休眠前已经调用了 interrupt() 方法,则这种中断操作称为待决中断
public static void main(String[] args) {
Thread.currentThread().interrupt();
System.out.println(Thread.currentThread().isInterrupted());
long start = System.currentTimeMillis();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println(end - start);
System.out.println(Thread.currentThread().isInterrupted());
}
运行结果:
从运行结果可以看出,起止时间差微乎其微(2毫秒),线程根本没有经历 10 秒的休眠,因为线程在休眠前已经被调用了 interrupt() 方法,所以线程调用 sleep() 休眠时会立刻抛出 InterruptedException 异常,并不会真正执行休眠操作。需要注意的是 sleep() 方法会清空线程中断标志,再次打印出的线程中断状态变为了 false。