Java 线程中断机制,interrupt 源码解析 - Thread 中断系列全搞定

本文详细探讨了Java线程中断的概念,包括协作式和抢占式调度方式,以及Thread类中的isInterrupted()、interrupt()和interrupted()方法的工作原理。通过源码分析和示例,展示了如何在不同场景下使用这些方法来管理和响应线程中断,同时解释了中断状态与操作系统的关系。
摘要由CSDN通过智能技术生成

前言

Java并发知识体系持续更新:https://blog.csdn.net/m0_46144826/category_9881831.html

开始之前老规矩,把源码放上:


一个线程执行完毕之后会自动结束,如果在运行过程中发生异常也会提前结束。

线程中断是一个非常重要的概念,中断线程是取消任务最好的方法。

在 Java 的 Thread 类中,提供了以下三个关于线程中断的 public 方法:

  • void interrupt() ,中断线程。
  • static boolean interrupted() ,测试当前线程是否已被中断。通过此方法可以清除线程的中断状态。
  • boolean isInterrupted() ,测试线程是否已经中断,线程的中断状态不受该方法的影响。

这三个是线程的公共方法,但是它的最底层是两个 native 方法:

    private native void interrupt0(); //中断线程
    /**
     * 测试某些线程是否已被中断。线程的中断状态不受此方法的影响。
     * ClearInterrupted参数决定线程中断状态是否被重置,若为true则重置。
     */
    private native boolean isInterrupted(boolean ClearInterrupted);

从这里就可以发现:

线程的中断状态,并不是由 Java 来决定。实际上,Thread 类中并没有维护线程的中断状态。


协作式和抢占式

然后,就有了下一个问题:

中断状态是个啥玩意儿???线程中断难道不是终止线程嘛?为什么还会有状态?Thread 类里面也没有这个状态变量啊,难道操作系统内给线程添加了这个状态?

所以,又又又又得百度去咯。。。根据各位大佬们的博客,个人感觉应该是这样的:

  1. 明确线程中断状态不是 Thread 类的标志位,而是操作系统中对线程的中断标志。

这一结论来自 native 方法:

    /**
     * 测试某些线程是否已被中断。线程的中断状态不受此方法的影响。
     * ClearInterrupted参数决定线程中断状态是否被重置,若为true则重置。
     */
    private native boolean isInterrupted(boolean ClearInterrupted);

很明显了,在操作系统对线程的管理中,确实存在一个中断状态的标志位。


  1. 操作系统调度线程的方式:协作式、抢占式
  • 协作式:线程自己的工作执行完后,要主动通知调度切换到另一个线程上。 如果一个线程编写有问题,一直不告知系统进行线程切换,那么程序就会一直阻塞在那里。线程的执行时间由自身掌控。
  • 抢占式:线程将由调度来分配执行时间,线程的切换不由线程自身决定。 不会出现一个线程导致整个进程阻塞的问题。

Java 的线程中断,也作为协作式中断,调用 interrupt() 方法最终也只是更改操作系统中的中断标志位,线程是否中断,由线程自身决定。


isInterrupted()

测试线程是否已经中断,线程的中断状态不受该方法的影响。

    /**
     * 测试此线程是否已被中断。线程的中断状态不受此方法的影响。
     * <p>如果中断时,线程并没有存活,那么该方法返回 false。意思就是,如果线程还没有 start 启动,或者已经消亡,那么返回依然是 false.
     * @return  如果该线程已被中断,返回true;否则返回 false
     */
    public boolean isInterrupted() {
   
        //不清除中断状态
        return isInterrupted(false);
    }

这是最基础的判断中断状态,且不更改 OS 线程中断标志位。可以对照上面的 native 方法阅读。特别的记一下这两句:

如果线程还没有 start 启动,或者已经消亡,那么返回依然是 false。中断状态只代表是否有线程调用中断方法。

举个栗子看下效果就行:

   public static class Example extends Thread{
   
        @Override
        public void run
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值