【问题标题】:Unhandled exceptions with Java scheduled executorsJava 计划执行程序的未处理异常
【发布时间】:2009-11-02 11:48:52
【问题描述】:

我有以下问题,我想知道到底发生了什么。我使用 Java 的 ScheduledExecutorService 每五分钟运行一次任务。它工作得很好。 Executors 彻底改变了我在 Java 中进行线程编程的方式。

现在,我浏览了 Java Doc 以获取有关在计划任务因未处理的异常而失败但找不到任何内容时会发生什么行为的信息。

下一个计划任务还会运行吗?如果有未处理的异常,被调度的executor停止调度任务?任何人都可以指出有关这个简单问题的信息吗?

非常感谢。

【问题讨论】:

    标签: java exception-handling multithreading executor


    【解决方案1】:

    scheduleAtFixedRatescheduleWithFixedDelay 的 Javadoc 都说“如果任务的任何执行遇到异常,后续执行将被禁止。”我觉得这不是很清楚,但似乎是在说如果您的 run 方法抛出任何类型的异常,那么调度程序将有效地放弃该任务。通过该调度程序运行的任何其他任务不应受到影响。测试它的实际作用应该不难......

    取消任务不一定是坏事。如果run方法抛出RuntimeException,可能是某处有bug,系统状态未知。但至少我会建议在你的运行方法中捕获RuntimeException,并在 SEVERE 记录完整的堆栈跟踪。您可能需要重新抛出以取消任务,具体取决于具体情况。但无论哪种方式,您都需要伐木才能找出问题所在。

    【讨论】:

    • 非常感谢您的回复。我在 API Doc 中没有看到。
    • 快速浏览 ThreadPoolExecutor 的源代码(在其上实现了 STPE)表明 RuntimeExceptions 将被巧妙地捕获并通过 ScheduledFuture 报告回来,但它们也会导致工作线程终止。 TPE 将注意到此工作线程终止,并在必要时启动新的替换。请参阅 JDK 源代码中的 java.util.concurrent.ThreadPoolExecutor 或 Doug Lea 网站上的 runWorker() 和 processWorkerExit()。
    【解决方案2】:

    如果您使用scheduleAtFixedRate()scheduleAtFixedDelay(),并且您的任务因异常退出,则该任务将不会被重新安排。但是,其他独立任务应继续按预期执行。 (见API Docs)。如果您关心这是否发生,您可以获取返回的ScheduledFuture 并调用get() 方法。如果底层任务抛出异常,您将把它从 get() 方法中抛出,并包裹在 ExecutionException 中。

    【讨论】:

    • 非常感谢您的回复。 +1。太糟糕了,我不能接受两个答案作为“答案”。再次感谢。
    • 嘿,伙计,Lachlan 打败了我……规则就是规则。 ;-)
    • 奇怪..我的连续任务也停止了。
    【解决方案3】:

    这个人也有同样的问题。

    http://code.nomad-labs.com/2011/12/09/mother-fk-the-scheduledexecutorservice/

    他的解决方案是在 runnable 中捕获 Exception 并重新抛出 RuntimeException

    try {
           theRunnable.run();
        } catch (Exception e) {
           // LOG IT HERE!!!
           System.err.println("error in executing: " + theRunnable + ". It will no longer be run!");
           e.printStackTrace();
    
           // and re throw it so that the Executor also gets this error so that it can do what it would
           // usually do
           throw new RuntimeException(e);
    }
    

    【讨论】:

      【解决方案4】:

      看起来 API 没有定义任何特定的异常处理机制。 IE。未捕获的异常只是通过线程框架弹出并最终被记录到标准错误。

      我发现您可以利用以下异常处理策略:

      【讨论】:

      • 我认为没有记录这些异常。
      猜你喜欢
      • 2011-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多