当前位置: 首页 > 知识库问答 >
问题:

服务中断lib,lib随后抛出InterruptException,但不会被服务代码捕获

岳朝
2023-03-14

在服务代码中,我有一个ScheduledTaskExecutor来启动一个作业,然后是第二个线程,它将通过中断来取消第一个线程。作业间歇性地检查中断,当作业得到中断时,它将抛出中断异常;该服务对该作业有一个try/catch,catch处理该中断。我的问题是,挡块永远不会被击中。作业肯定被中断了,从作业端的日志语句中可以清楚地看到,一旦抛出InterruptException,它就会丢失,服务也无法捕获它。

我试着换线。中断()到线程。currentThread()。interrupted(),但没有解决问题。

下面是等待作业中断异常的服务器端代码。中断信号通过计划在超时后运行的另一个线程发送给线程。我已经确认作业确实收到了中断信号。

    private void run() {
        try {
            job.run();
        } catch (InterruptedException e) {
            log.info("Job was interrupted", e);
        } finally {
            duration.stop();
            timer.record(duration);
        }
    }

以下是作业如何检查中断:

    public void checkForInterrupt() throws InterruptedException {
        if (Thread.currentThread().isInterrupted()) {
            logger.info(jobName + " was interrupted");
            throw new InterruptedException(jobName + " has been interrupted");
        }
    }

我希望看到这个日志行log.info("作业被中断", e);我从线程听到的最后一件事是一个日志语句,确认它的中断标志已设置,之后它抛出InterruptedException。

共有1个答案

蒯宏达
2023-03-14

作业肯定被中断了,从作业端的日志语句中可以清楚地看到,一旦抛出InterruptException,它就会丢失,服务也无法捕获它。

这是一个常见问题。每当抛出InterruptedException时,线程上的中断标志就会被清除。如果您需要使线程静止中断,则需要重新中断它。这始终是捕获InterruptedException时的正确模式。原因是如果您正在编写某种库,您不想吞下中断标志,这意味着调用者不知道线程是否被中断。中断线程被设计为一种优雅的关闭(与已弃用的Stop()方法相反)。因此传播中断线程始终是一种很好的模式。

例如:

   ...
} catch (InterruptedException e) {
   // we always should re-interrupt the thread when we catch InterruptedException
   Thread.currentThread().interrupt();
   log.info("Job was interrupted", e);

然后,当您返回调用方时,可以测试中断标志:

if (Thread.currentThread().isInterrupted()) {
   ...

如果您想了解有关抛出InterruptedException的各种方法以及影响标志的各种Thread方法的更多详细信息,请参阅我的答案:清除Thread.interrupt()标志的方法

例如,人们永远不应该使用Thread.interrupted(),因为这会在测试中断标志时清除它。您对Thread.currentThread(). is中断()的使用是正确的。

 类似资料:
  • 在处理消息时,我不断收到。 我正在使用Microsoft. Azure. ServiceBus 3.2.0和. NET Core 2.1。 我有一个锁持续时间设置为30秒的队列,其中已经包含了许多要处理的消息。 我从https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-dotnet-get-started-

  • 我需要实现一个预定的执行器服务,它每隔x秒运行一个线程。线程执行应该中断,以防它需要超过y秒。我曾尝试使用SchduledExecutorService实现该解决方案,该解决方案具有可配置的间隔参数,但没有超时参数。我有一些想法,我想听听你对实现/技术的建议。

  • Googleapi版本:libs-sources/google-api-services-drive-v2-rev168-1.20.0-sources.jar java版本:“1.7.0_79”java(TM)SE运行时环境(build 1.7.0_79-B15)java HotSpot(TM)64位服务器VM(build 24.79-B02,混合模式) 还将下载的p12文件加载到\jdk1.7.

  • 我的项目使用spring框架来处理http请求和响应。我请求用redis或数据库中的值替换一些参数,这些值取决于其中一个参数。 我调查的大多数相关案例都是使用过滤器来达到目的的。 例如,api有两个参数CusterName: abc, isNickName: true。我尝试实现一个类,它扩展了如下所示的OncePerrecestFilter类。 在网上。xml 我尝试使用@AutoWired a

  • 我有一个后台服务,每天下午1点打电话给我。下午1点,我的Firebase数据库中的3个值应设置为0。当用户启动某个活动时,会触发后台服务。如我所愿,值在下午1点重置为0,但每次下午1点后,当用户启动活动时,服务都会运行重置我的值。如何在下午1点将值重置为0,直到第二天下午1点才再次重置? 下面是我在服务类中的代码 这是启动服务的代码。此方法在此活动的oncreate方法中调用。

  • 当你想要分享你代码给其他人,或者是你需要在另外一台电脑上工作时,托管代码就会是一个非常重要的话题。基本上代码托管有两种不同的形式: do-it-yourself(建立一个自己的)或者 leave-me-in-peace(使用第三方提供的平台,不麻烦自己)。 (A) Do-It-Yourself 把你的 Git 仓库托管在你自己的服务器上会有很多的优点: 可以节省你花在代码托管服务上的费用。 你的代