资讯专栏INFORMATION COLUMN

Thread中interrupt使用方法

FingerLiu / 3426人阅读

摘要:合理中断线程合理中断在类中提供了和方法这三个方法分别是用来结束暂停恢复线程但是都已经被标记为废弃了因为一个线程不应该由其他线程来结束他应该收到别人的通知然后自己在合适的位置结束如果不合理的结束会导致很多意外的结果比如临界区还没完全操作完提前

合理中断线程 合理中断

Thread类中,提供了stop(),suspend()resume()方法,这三个方法分别是用来结束,暂停,恢复线程. 但是都已经被标记为@Deprecated废弃了. 因为一个线程不应该由其他线程来结束,他应该收到别人的通知,然后自己在合适的位置结束,如果不合理的结束,会导致很多意外的结果,比如临界区还没完全操作完,提前释放锁,但是部分状态已经改变,还有没有做一些清理操作等等.

基于上面的理由,Java提供了新的中断机制(interrupt),其他线程调用想要终止线程的interrupt()方法. 这个时候线程会根据自己的状态做出响应:

如果线程处于阻塞状态(sleep,wait,join),则线程会抛出InterruptedException异常.

如果线程处于正常运行状态,则还是正常运行,但是中断的标志被设置为true,相当于有人通知 你该结束自己了.

被调用线程处于阻塞状态
public static void main(String[] args) {
    Thread thread = new Thread() {
        @Override
        public void run() {
            try {
                // 被调线程阻塞自己30s
                sleep(30000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    };
    try {
        // 启动线程
        thread.start();
        // 主线程阻塞自己3秒
        TimeUnit.SECONDS.sleep(3);
        // 中断线程
        thread.interrupt();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}
// ↓ out ↓
// java.lang.InterruptedException: sleep interrupted
// ...
被调用线程处于正常运行

被调用线程不处于阻塞的时候,需要调用方法来监控标志.

public static void main(String[] args) {
    Thread thread = new Thread() {
        @Override
        public void run() {
            while (!Thread.interrupted()) {
                System.out.println("我还稳得住...");
            }
        }
    };
    try {
        thread.start();
        TimeUnit.SECONDS.sleep(3);
        thread.interrupt();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

// ↓ out ↓
// 我能稳得住
// ...

该程序会在检测interrupt标志,如果发现interrupt标志设置为true,则会结束自己.

interrupted()和isInterrupt()的区别

区别: 是否会清除interrupt标志. isInterrupt()方法不会改变标志,而interrupted()方法会在检测的同时,如果发现标志为true,则会返回true,然后把标志置为false.

public static void main(String[] args) {
    Thread thread = new Thread() {
        @Override
        public void run() {
            while (!Thread.interrupted()) {
                System.out.println("我还稳得住...");
            }
            // ⚠️⚠️添加下面代码⚠️⚠️
            System.out.println(Thread.interrupted());
        }
    };
    try {
        thread.start();
        TimeUnit.SECONDS.sleep(3);
        thread.interrupt();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

// ↓ out ↓
// 我还稳得住...
// ...(省略)
// false

上面实例说明Thread.interrupted()方法会在标志为true的情况下修改interrupted的标志.

public static void main(String[] args) {
    Thread thread = new Thread() {
        @Override
        public void run() {
            // ⚠️⚠️修改方法⚠️⚠️
            while (!isInterrupted()) {
                System.out.println("我还稳得住...");
            }
            System.out.println(Thread.interrupted());
        }
    };
    try {
        thread.start();
        TimeUnit.SECONDS.sleep(3);
        thread.interrupt();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

// ↓ out ↓
// 我还稳得住...
// ...(省略)
// true
源码解析

通过观察源码可以看出interrupted方法最后会调用isInterrupted(true)方法,而传入的参数代表是否清除标志位. 可以看到isInterrupted(boolean)是一个本地方法,最终会通过C/C++来执行. 而isInterrupted()最后传入的参数为false,说明不清除标志位.

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/77706.html

相关文章

  • (三)从jvm层面了解线程的启动和停止

    摘要:最后我们重点关注与一下实际就是调用平台创建线程的方法来创建线程。线程的中断标识判断了解了方法的作用以后,再回过头来看中这段代码,就很好理解了。 文章简介 这一篇主要围绕线程状态控制相关的操作分析线程的原理,比如线程的中断、线程的通信等,内容比较多,可能会分两篇文章 内容导航 线程的启动的实现原理 线程停止的实现原理分析 为什么中断线程会抛出InterruptedException ...

    mudiyouyou 评论0 收藏0
  • Thread类源码解读(3)——线程interrupt

    摘要:现在终止一个线程,基本上只能靠曲线救国式的中断来实现。中断机制的核心在于中断状态和异常中断状态设置一个中断状态清除一个中断状态方法同时会返回线程原来的中断的状态。中断异常中断异常一般是线程被中断后,在一些类型的方法如中抛出。 前言 系列文章目录 线程中断是一个很重要的概念,通常,取消一个任务的执行,最好的,同时也是最合理的方法,就是通过中断。 本篇我们主要还是通过源码分析来看看中断的概...

    fevin 评论0 收藏0
  • java线程池的生命周期与线程

    摘要:线程中断线程中断就是一种协作机制。它并不会真正的中断一个正在运行的线程,而只是发出中断请求,然后由线程在下一个合适的时刻中断自己。 线程池生命周期包括: RUNNING:接收新的任务并处理队列中的任务 SHUTDOWN:不接收新的任务,但是处理队列中的任务 STOP:不接收新的任务,不处理队列中的任务,同时中断处理中的任务 TIDYING:所有的任务处理完成,有效的线程数是0 TER...

    suxier 评论0 收藏0
  • 线程的断 - Interrupts

    摘要:我们通常使用中断去终止线程如何中断线程调用,向线程发送指示。当获取到指示时,这些方法将抛出异常。捕获这个异常,并即可中断线程。 Interrupt ? An interrupt is an indication to a thread that it should stop what it is doing and do something else. 中断(interupt)是一个指...

    chenatu 评论0 收藏0
  • Java Executors 源码分析

    摘要:表示一个异步任务的结果,就是向线程池提交一个任务后,它会返回对应的对象。它们分别提供两个重要的功能阻塞当前线程等待一段时间直到完成或者异常终止取消任务。此时,线程从中返回,然后检查当前的状态已经被改变,随后退出循环。 0 引言 前段时间需要把一个C++的项目port到Java中,因此时隔三年后重新熟悉了下Java。由于需要一个通用的线程池,自然而然就想到了Executors。 用了...

    itvincent 评论0 收藏0

发表评论

0条评论

FingerLiu

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<