【JavaSE专栏82】线程中断,发送一个中断信号给另一个线程,让它中断当前的执行

简介: 【JavaSE专栏82】线程中断,发送一个中断信号给另一个线程,让它中断当前的执行

本文讲解了 Java 中线程中断的语法和应用场景,并给出了样例代码。线程中断指的是一个线程发送一个中断信号给另一个线程,通知其应该中断当前的执行。

一、什么是线程中断

线程中断指的是一个线程发送一个中断信号给另一个线程,通知其应该中断当前的执行

线程中断并不会直接停止线程的执行,而是通过设置一个中断标志位来告知线程应该中断,被中断的线程可以根据中断标志位来决定是否继续执行,通常是通过捕获并处理 InterruptedException 异常来检查中断标志位。

线程中断的主要作用是在多线程编程中,提供一种机制来协调和管理线程的执行。

通过中断线程,可以优雅地终止一个线程的执行,而不是强制终止,从而避免资源泄漏和不一致的状态。通过中断标志位,线程可以在适当的时候进行一些清理操作,释放资源,然后正常地结束线程的执行。

Java 中提供了以下 3 33 种方法来进行线程中断操作,请同学们认真学习。

  • interrupt():用于中断线程,将线程的中断标志位置为 t r u e truetrue
  • isInterrupted():用于检查线程的中断标志位,返回布尔值。
  • static interrupted():用于检查线程的中断标志位,并清除中断标志位,返回布尔值。

提示:仅仅通过调用 interrupt() 方法并不会中断一个线程的执行,需要在线程的逻辑中采取相应的措施来检测中断标志位并结束线程的执行。常见的做法是在循环体中检查中断标志位,如果发现中断标志位为 t r u e truetrue,则跳出循环,终止线程的执行。


二、线程什么情况下需要中断

在以下 4 44 种情况下,可以考虑中断 Java 线程,请同学们做一个简单了解。

  1. 外部中断请求:当其他线程或者外部资源需要中断当前线程时,可以通过调用线程的 interrupt() 方法来发送中断请求。例如,当用户点击取消按钮时,可以中断正在执行的任务线程。
  2. 长时间等待:当线程在等待某个资源或者条件时,可以通过中断来提前结束等待。例如,线程在等待网络请求的响应时,可以设置一个超时时间,超过该时间还未收到响应,可以中断线程。
  3. 安全退出:在多线程应用中,当需要退出整个应用时,可以通过中断所有线程来实现优雅的退出。例如,当主线程接收到退出信号时,可以中断所有工作线程,并等待它们结束。
  4. 处理异常情况:在某些情况下,线程可能会发生异常,导致无法继续正常执行。通过捕获异常并中断线程,可以及时处理异常情况,避免程序继续运行下去产生更多的错误。

线程中断只是发送一个中断请求,而不是立即停止线程的执行。被中断的线程需要在适当的时候检查中断标志位,并决定是否终止线程的执行。

同时,中断标志位可以被线程忽略,因此在使用线程中断时,需要在代码中妥善处理中断信号,以确保线程能够正确响应中断请求


三、模拟线程中断

以下是使用 Java 模拟线程中断的示例代码,请同学们复制到本地执行。

public class InterruptExample implements Runnable {
    @Override
    public void run() {
        while (!Thread.currentThread().isInterrupted()) {
            System.out.println("Thread is running...");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                System.out.println("Thread is interrupted!");
                // 恢复中断状态
                Thread.currentThread().interrupt();
            }
        }
        System.out.println("Thread is stopped!");
    }
    public static void main(String[] args) {
        Thread thread = new Thread(new InterruptExample());
        thread.start();
        try {
            // 主线程休眠3秒后中断子线程
            Thread.sleep(3000);
            thread.interrupt();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

在上述代码中,我们创建了一个实现了 Runnable 接口的类 InterruptExample,其中的 run() 方法是子线程的执行逻辑。

run() 方法中,线程会不断打印信息,然后通过调用 Thread.sleep(1000) 来模拟线程的执行过程。

run() 方法中,我们通过 Thread.currentThread().isInterrupted() 来检查线程的中断状态。

如果中断状态为 f a l s e falsefalse,即线程未被中断,则继续执行循环。当线程在休眠过程中被中断时,将会抛出 InterruptedException 异常。

在异常处理的代码块中,我们输出中断信息,并通过 Thread.currentThread().interrupt() 恢复线程的中断状态。

main() 方法中,我们创建了一个子线程,并启动它,然后在主线程休眠 3 33 秒后,调用子线程的 interrupt() 方法,向子线程发送中断请求,子线程会根据中断请求来决定是否中断自己的执行。

运行代码后,可以看到子线程在每秒打印一次信息,主线程休眠 3 33 秒后,子线程收到中断请求,输出中断信息,并终止执行。


四、线程中断的应用场景

线程中断在 Java 多线程编程中有许多应用场景,以下是 5 55 个常见的示例,请同学们认真学习。

  1. 取消长时间等待:当线程在等待某个资源或者条件的时候,可以通过中断来提前结束等待。例如,网络请求超时、等待锁超时等情况下,可以中断线程以避免无限等待。
  2. 终止执行:当某个线程的执行条件不再满足时,可以使用线程中断来终止其执行。例如,当一个任务已经完成或者不再需要时,可以中断执行该任务的线程。
  3. 优雅的退出:在多线程应用中,当需要退出整个应用时,可以通过中断所有线程来实现优雅的退出。例如,当主线程接收到退出信号时,可以中断所有工作线程,并等待它们结束。
  4. 异常处理:在某些情况下,线程可能会发生异常,导致无法继续正常执行。通过捕获异常并中断线程,可以及时处理异常情况,避免程序继续运行下去产生更多的错误。
  5. 控制并发操作:线程中断可以用于控制并发操作的执行流程。例如,当多个线程同时执行某个任务时,可以使用中断来通知其他线程停止执行,或者中断其他线程以提高执行效率。

线程中断只是发送一个中断请求,而不是立即停止线程的执行。被中断的线程需要在适当的时候检查中断标志位,并决定是否终止线程的执行。

同时,中断标志位可以被线程忽略,因此,在使用线程中断时,需要在代码中妥善处理中断信号,以确保线程能够正确响应中断请求。


五、线程中断面试题

一、什么是 Java 线程中断?

答:Java 线程中断是通过发送中断请求来终止线程的执行,中断请求是通过调用线程的 interrupt() 方法发送的,被中断的线程可以检查中断标志位来决定是否终止执行。

二、如何中断一个线程?

答:可以通过调用线程的 interrupt() 方法来中断线程,interrupt() 方法会设置线程的中断标志位为 t r u e truetrue,被中断的线程需要在适当的时候检查中断标志位,并决定是否终止执行。

三、线程中断与线程停止有什么区别?

答:线程中断是通过发送中断请求来终止线程的执行,而线程停止是直接停止线程的执行,线程中断是一种安全的终止线程的方式,被中断的线程可以在适当的时候检查中断标志位并决定是否终止执行。

四、如何检查线程的中断状态?

答:可以通过调用线程的 isInterrupted() 方法来检查线程的中断状态,isInterrupted() 方法返回当前线程的中断状态,如果线程被中断,则返回 t r u e truetrue,否则返回 f a l s e falsefalse

五、中断状态会自动清除吗?

答:中断状态不会自动清除,一旦线程被中断,它的中断状态会一直保持,即使在执行过程中发生了异常或者调用了其他方法,需要开发者手动清除中断状态,可以通过 Thread.interrupted() 方法来清除中断状态。

六、如何响应线程中断?

答:线程可以在适当的时候检查中断标志位,并决定是否终止执行,通常线程可以在循环中使用 isInterrupted() 方法检查中断标志位,然后在合适的地方终止循环或者完成后续操作。


六、总结

本文讲解了 Java 中线程中断的语法和应用场景,并给出了样例代码,在下一篇博客中,将讲解 Java 线程插队的问题。


相关文章
|
1月前
|
消息中间件 存储 算法
【软件设计师备考 专题 】操作系统的内核(中断控制)、进程、线程概念
【软件设计师备考 专题 】操作系统的内核(中断控制)、进程、线程概念
83 0
|
1月前
|
Java API 调度
线程的中断(interrupt)机制
线程的中断(interrupt)机制
30 1
|
6月前
|
Java 调度 开发者
【JavaSE专栏84】线程让步,一种线程调度的机制
【JavaSE专栏84】线程让步,一种线程调度的机制
|
6月前
|
Java 调度
【JavaSE专栏81】线程休眠,一种暂停线程执行的方法
【JavaSE专栏81】线程休眠,一种暂停线程执行的方法
118 0
|
2天前
|
安全 算法 Java
JavaSE&多线程&线程池
JavaSE&多线程&线程池
17 7
|
6月前
|
并行计算 安全 Java
【JavaSE专栏80】多线程通信,多个线程之间如何实现信息传递和同步?
【JavaSE专栏80】多线程通信,多个线程之间如何实现信息传递和同步?
|
6月前
|
JSON 安全 Java
【JavaSE专栏87】线程终止问题,什么情况下需要终止线程,如何终止Java线程?
【JavaSE专栏87】线程终止问题,什么情况下需要终止线程,如何终止Java线程?
|
6月前
|
监控 Java 数据库连接
【JavaSE专栏86】守护线程的那些事,后台默默地守护,是最长情的告白
【JavaSE专栏86】守护线程的那些事,后台默默地守护,是最长情的告白
|
6月前
|
Java 调度
【JavaSE专栏85】线程优先权,线程调度谁先谁后一目了然
【JavaSE专栏85】线程优先权,线程调度谁先谁后一目了然
314 0
|
6月前
|
Java
【JavaSE专栏83】线程插队,一个线程在另一个线程执行特定任务之前先执行
【JavaSE专栏83】线程插队,一个线程在另一个线程执行特定任务之前先执行