Java 多线程:线程中断

本文内容大多基于官方文档和网上前辈经验总结,经过个人实践加以整理积累,仅供参考。


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。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

又言又语

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值