Java.lang.InterruptedException被中止异常解决方案

裴景
• 阅读 255

大家好!我是咕噜铁蛋!在Java编程的世界里,java.lang.InterruptedException是一个常见的异常,尤其是在处理多线程和并发任务时。这个异常通常表示一个线程在等待、休眠或其他占用时间不长的操作时被中断。作为一个资深的Java开发者,我想通过这篇文章和大家分享一下我对这个异常的理解以及应对它的解决方案。
一、认识InterruptedException
InterruptedException是Java中定义的一个检查型异常(checked exception),它必须被显式地捕获或声明抛出。当一个线程在等待、休眠或进行其他可中断的阻塞操作时,另一个线程可以调用其interrupt()方法来中断它。如果被中断的线程正在执行一个可中断的阻塞操作,那么该阻塞操作会立即抛出InterruptedException,从而允许线程能够提前结束阻塞状态并处理中断请求。
二、为什么会出现InterruptedException
在Java中,线程的中断是一个协作机制,而不是强制机制。这意味着一个线程不能直接停止另一个线程的执行,而只能通过发送中断信号来请求线程自行停止。当线程收到中断信号时,它可以选择立即停止正在执行的任务,也可以选择继续执行,但在执行过程中需要不断检查中断状态。
当线程在等待或休眠时,它处于阻塞状态,无法执行任何代码。此时,如果其他线程调用了它的interrupt()方法,那么阻塞操作会立即抛出InterruptedException,从而唤醒阻塞线程。这样,阻塞线程就能够感知到中断信号,并根据需要进行相应的处理。
三、InterruptedException的处理策略
处理InterruptedException时,我们需要遵循一些基本原则来确保线程的正确性和健壮性。以下是一些常见的处理策略:

  1. 恢复中断状态
    当捕获到InterruptedException时,应该首先通过调用Thread.currentThread().interrupt()来恢复中断状态。这是因为如果在捕获异常后没有恢复中断状态,那么后续的代码可能无法感知到中断请求,从而导致线程无法正确响应中断。
  2. 处理或重新抛出异常
    根据线程的具体任务和处理逻辑,可以选择在捕获InterruptedException后直接处理它(例如记录日志、清理资源等),或者将其重新抛出给上层调用者处理。重新抛出异常时,应该使用throw new InterruptedException()(而不是直接抛出捕获的异常对象),以确保异常信息的完整性和准确性。
  3. 避免在循环中捕获并忽略异常
    如果在一个循环中反复捕获并忽略InterruptedException,那么线程可能会一直阻塞在循环中而无法响应中断请求。因此,在循环中应该谨慎处理该异常,避免造成线程的死锁或资源浪费。
  4. 正确使用wait()notify()notifyAll()方法
    当使用wait()notify()notifyAll()方法进行线程间的通信时,需要特别注意这些方法的可中断性。在调用这些方法时,应该使用try-catch块来捕获并处理InterruptedException,以确保线程能够在收到中断信号时及时响应。
  5. 避免在不可中断的阻塞操作中捕获异常
    有些阻塞操作是不可中断的(例如ServerSocket.accept()DataInputStream.read()等),这些操作在收到中断信号时不会抛出InterruptedException。因此,在调用这些方法时,应该避免捕获InterruptedException,以免造成混淆和错误处理。
    四、示例代码
    下面是一个简单的示例代码,展示了如何处理InterruptedException
public class InterruptedExceptionExample implements Runnable {

    @Override
    public void run() {
        try {
            // 模拟一个可中断的阻塞操作
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            // 恢复中断状态
            Thread.currentThread().interrupt();
            // 处理中断请求(例如记录日志、清理资源等)
            System.err.println("Thread interrupted: " + e.getMessage());
            // 线程退出
            return;
        }
        // 如果没有被中断,则继续执行后续任务...
    }

    public static void main(String[] args) {
        Thread thread = new Thread(new InterruptedExceptionExample());
        thread.start();

        // 主线程等待一段时间后中断子线程
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            // 处理主线程的中断请求...
        }
        thread.interrupt();
    }
}

InterruptedException是Java多线程编程中一个重要的异常类型,它表示线程在等待、休眠或其他阻塞操作时被中断。正确处理这个异常对于保证线程的正确性和健壮性至关重要。通过恢复中断状态、处理或重新抛出异常、避免在循环中捕获并忽略异常以及正确使用线程间的通信方法等措施,我们可以有效地应对

点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
3年前
Java多线程并发控制工具CountDownLatch,实现原理及案例
闭锁(CountDownLatch)是Java多线程并发中的一种同步器,它是JDK内置的同步器。通过它可以定义一个倒计数器,当倒计数器的值大于0时,所有调用await方法的线程都会等待。而调用countDown方法则可以让倒计数器的值减一,当倒计数器值为0时所有等待的线程都将继续往下执行。闭锁的主要应用场景是让某个或某些线程在某个运行节点上等待N个条件都
Wesley13 Wesley13
3年前
03.Android崩溃Crash库之ExceptionHandler分析
目录总结00.异常处理几个常用api01.UncaughtExceptionHandler02.Java线程处理异常分析03.Android中线程处理异常分析04.为何使用setDefaultUncaughtExceptionHandler前沿上一篇整体介绍了crash崩溃
可莉 可莉
3年前
10 个深恶痛绝的 Java 异常。。
异常是Java程序中经常遇到的问题,我想每一个Java程序员都讨厌异常,一个异常就是一个BUG,就要花很多时间来定位异常问题。什么是异常及异常的分类请看这篇文章:一张图搞清楚Java异常机制(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fmp.weixin.qq
Wesley13 Wesley13
3年前
J2EE项目异常处理
       为什么要在J2EE项目中谈异常处理呢?可能许多java初学者都想说:“异常处理不就是try….catch…finally吗?这谁都会啊!”。笔者在初学java时也是这样认为的。如何在一个多层的j2ee项目中定义相应的异常类?在项目中的每一层如何进行异常处理?异常何时被抛出?异常何时被记录?异常该怎么记录?何时需要把checkedExc
Wesley13 Wesley13
3年前
初探 Objective
作者:Cyandev,iOS和MacOS开发者,目前就职于字节跳动0x00前言异常处理是许多高级语言都具有的特性,它可以直接中断当前函数并将控制权转交给能够处理异常的函数。不同语言在异常处理的实现上各不相同,本文主要来分析一下ObjectiveC和C这两个语言。为什么要把ObjectiveC和
Stella981 Stella981
3年前
Python并发(二)
并发是指一次处理多件事,而并行是指一次做多件事。二者不同,但互相有联系。打个比方:像Python的多线程,就是并发,因为Python的解释器GIL是线程不安全的,一次只允许执行一个线程的Python字节码,我们在使用多线程时,看上去像很多个任务同时进行,但实际上但一个线程在执行的时候,其他线程是处于休眠状态的。而在多CPU的服务器上,Java或Go的多线程,
Wesley13 Wesley13
3年前
JAVA学习笔记 之 异常
异常的概述代码在运行时期发生的问题就称之为异常。在java中,异常被封装成为了一个类,当程序出现了异常类中的问题时,异常的信息(如位置和原因)就会被抛出。在java中用Exception来描述异常,publicclassExceptionextendsThrowable则是异常的继承体系。 Throwable是所有错误或异常的
Stella981 Stella981
3年前
Linux并发与同步专题
并发访问:多个内核路径同时访问和操作数据,就有可能发生相互覆盖共享数据的情况,造成被访问数据的不一致。临界区:访问和操作共享数据的代码段。并发源:访问临界区的执行线程或代码路径。在内核中产生并发访问的主要有如下4种:中断和异常:中断发生后,中断处理程序和被中断的进程之间有可能产生并发访问。中断<被中断的线程软中断和ta
Stella981 Stella981
3年前
SpringBoot过滤器中的异常处理
在昨天的文章我跟大家分享了SpringBoot中异常的处理中,我说了一个需要注意的点,就是过滤器中抛出的异常无法被异常处理类捕获,然后这个朋友就问应该如何处理。其实处理这种问题的处理方式有好几种,那么我就简单分享一下我近期一个项目中的处理方式。Filter中的异常处理思路首先我们要明白,在过滤器中我们一般是不会写很长
Easter79 Easter79
3年前
SpringBoot过滤器中的异常处理
在昨天的文章我跟大家分享了SpringBoot中异常的处理中,我说了一个需要注意的点,就是过滤器中抛出的异常无法被异常处理类捕获,然后这个朋友就问应该如何处理。其实处理这种问题的处理方式有好几种,那么我就简单分享一下我近期一个项目中的处理方式。Filter中的异常处理思路首先我们要明白,在过滤器中我们一般是不会写很长
京东云开发者 京东云开发者
5个月前
深入理解分布式锁:原理、应用与挑战
作者:京东物流刘浩前言在单机环境中,我们主要通过线程间的加锁机制来确保同一时间只有一个线程能够访问某个共享资源或执行某个关键代码块,从而防止各种并发修改异常。例如,在Java中提供了synchronized/Lock。但是在分布式环境中,这种线程间的锁机制