博客
关于我
不学无数——InterruptedException异常
阅读量:471 次
发布时间:2019-03-06

本文共 2887 字,大约阅读时间需要 9 分钟。

线程中断与InterruptedException异常处理

在线程编程中,线程中断是一个非常重要的概念。了解线程中断的原理和应用,可以帮助开发者更好地管理线程的生命周期,提升程序的稳定性和性能。

线程的状态与阻塞

线程在运行过程中会经历多种状态。这些状态决定了线程是否能够继续执行任务。了解线程的状态有助于我们更好地理解线程中断的机制。

线程的状态包括:

  • 初始 (NEW):新建线程尚未调用 start() 方法。
  • 运行 (RUNNABLE):线程处于就绪状态,准备执行任务。
  • 阻塞 (BLOCKED):线程因等待资源(如锁、I/O)而暂停执行。
  • 等待 (WAITING):线程因等待通知(notify()notifyAll())而处于休眠状态。
  • 超时等待 (TIME_WAITING):线程因调用 wait() 方法超时而处于休眠状态。
  • 终止 (TERMINATED):线程任务完成或被终止。

线程阻塞通常发生在以下场景:

  • 等待阻塞:线程调用 wait() 方法,释放所有资源,进入等待池,需其他线程调用 notify()notifyAll() 才能唤醒。
  • 同步阻塞:线程尝试获取同步锁时,因锁被占用而进入阻塞状态。
  • 其他阻塞:线程调用 sleep()join() 或等待I/O操作完成时,进入阻塞状态。

线程中断

线程中断机制允许一个线程在运行中被另一个线程中断,中断的意义在于可以在不等待阻塞线程完成任务的情况下,提前终止任务。

线程中断的实现机制包括:

  • 每个线程都有一个 boolean 标志,表示是否请求中断,默认为 false
  • 调用 interrupt() 方法可以将目标线程的 boolean 标志设置为 true,表明中断请求已发送。
  • 线程可以通过 isInterrupted() 方法检查自身的中断标志状态。

线程中断的处理方式:

  • 阻塞方法:如果线程处于阻塞状态(如 sleep()join()),调用 interrupt() 会立即将线程从阻塞状态中唤醒,并抛出 InterruptedException 异常。抛出异常的同时,线程的 boolean 标志会被重置为 false
  • 非阻塞方法:线程可以通过 isInterrupted() 检查中断标志,或者调用 interrupted() 方法检测。需要注意的是,静态方法 interrupted() 会重置标志为 false

处理InterruptedException异常

在捕获 InterruptedException 异常时,开发者需要谨慎处理中断标志,以确保程序能够正确响应中断请求。

处理步骤:

  • 捕获异常:使用 try-catch 结构捕获 InterruptedException 异常。
  • 恢复中断状态:在 catch 块中,调用 Thread.currentThread().interrupt() 方法,将中断标志重置为 true,以便更高层的线程检测到中断请求。
  • 处理中断逻辑:根据具体需求,在捕获异常后执行必要的中断处理任务。
  • 代码示例

    以下是一个使用 Runnable 接口实现线程中断的示例:

    public class InterrupTest implements Runnable {
    public void run() {
    try {
    while (true) {
    Boolean a = Thread.currentThread().isInterrupted();
    System.out.println("in run() - about to sleep for 20 seconds-------" + a);
    Thread.sleep(20000);
    System.out.println("in run() - woke up");
    }
    } catch (InterruptedException e) {
    // Restore the interrupted status
    Thread.currentThread().interrupt();
    Boolean c = Thread.interrupted();
    Boolean d = Thread.interrupted();
    System.out.println("c=" + c);
    System.out.println("d=" + d);
    }
    }
    public static void main(String[] args) {
    InterrupTest si = new InterrupTest();
    Thread t = new Thread(si);
    t.start();
    try {
    Thread.sleep(2000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println("in main() - interrupting other thread");
    t.interrupt();
    System.out.println("in main() - leaving");
    }
    }

    输出结果:

    in run() - about to sleep for 20 seconds-------false
    in main() - interrupting other thread
    in main() - leaving
    c=true
    d=false

    注意事项

  • 捕获异常后恢复中断状态:在捕获 InterruptedException 异常后,必须重新将线程的中断标志设置为 true,否则更高层的线程将无法检测到中断请求。
  • 谨慎处理中断标志:在非阻塞方法中,直接调用 interrupted() 会重置标志为 false,所以在检测中断状态后,可能需要手动恢复标志。
  • 优化代码结构:在实现 Runnable 的子类时,尽量减少 InterruptedException 异常的抛出,避免在非阻塞方法中抛出该异常。
  • 线程中断和 InterruptedException 异常的处理是线程编程中的核心知识。通过正确使用中断机制,可以显著提升线程程序的响应性和稳定性。

    转载地址:http://fdmbz.baihongyu.com/

    你可能感兴趣的文章
    MySQL 面试题汇总
    查看>>
    MySQL 面试,必须掌握的 8 大核心点
    查看>>
    MySQL 高可用性之keepalived+mysql双主
    查看>>
    mysql 默认事务隔离级别下锁分析
    查看>>
    Mysql--逻辑架构
    查看>>
    MySql-2019-4-21-复习
    查看>>
    mysql-5.7.18安装
    查看>>
    MySQL-Buffer的应用
    查看>>
    mysql-cluster 安装篇(1)---简介
    查看>>
    mysql-connector-java各种版本下载地址
    查看>>
    mysql-EXPLAIN
    查看>>
    mysql-group_concat
    查看>>
    MySQL-redo日志
    查看>>
    MySQL-【1】配置
    查看>>
    MySQL-【4】基本操作
    查看>>
    Mysql-丢失更新
    查看>>
    Mysql-事务阻塞
    查看>>
    Mysql-存储引擎
    查看>>
    mysql-开启慢查询&所有操作记录日志
    查看>>
    MySQL-数据目录
    查看>>