代码之家  ›  专栏  ›  技术社区  ›  thedevd

正在捕获Java可启动的重新启动线程的最佳方式

  •  3
  • thedevd  · 技术社区  · 7 年前

    我在Java中有以下代码

    @Override
    public void run() {
    
        logger.info("Thread Started:" + this.getName());
    
        try {
            runJob();
        } catch( Throwable e) {
            logger.error("Exception in running thread: " + this.getName() + ", restarting job", e);
            run();
        }
    }
    
    public void runJob() {
    
        while(true) {
           try {
               // Work here
           } catch(Exception e) {
               // log the exception
           }
        }
     }
    

    这段代码在任何情况下都会保持线程的活动性,这是恢复线程的唯一方法吗?

    这是我在读完所有答案后想到的另一种选择。让我知道这是否是保持线程永久活动的好方法,即使发生错误:

    @Override
    public void run() {
    
        logger.info("Thread Started:" + this.getName());
    
        while(true) {
          try {
            runJob();
          } catch( Throwable e) {
            logger.error("Exception in running thread: " + this.getName() + ", restarting job", e);
            }
        }
    }
    
    public void runJob() {
    
         try {
              // Work here
         } catch(Exception e) {
              // log the exception
         }
     }
    
    3 回复  |  直到 7 年前
        1
  •  7
  •   ernest_k Petronella    7 年前

    这与“线程”关系不大。重试逻辑可以在异常上实现,这是常见的做法。

    但是,捕捉 Throwable 显然是一件危险的事情。您将希望在选择错误(如超时、连接失败等)时重试,这当然需要对您的 runJob() 方法运行。

    除此之外,您的重试实现正在使 递归 也可能是坏的。最后会遇到堆栈溢出错误(以及 catch 它和你的 Throwbale 捕捉块,完全导致奇怪的行为)。而是循环和执行 运行作业() 重复。

    boolean retry = false;
    do {
        try {
            runJob();
            retry = false;
        } catch (SpecificException e) { //timeout, network failure exceptions
            logger.error("Exception in running thread: "
                + this.getName() + ", restarting job");
            retry = true;
        }
    } while(retry);
    

    您可能还需要添加一个计数器来限制重试次数。

        2
  •  3
  •   Nikolas Charalambidis    7 年前

    你不应该用 try-catch !

    此外,如果在 catch ,它将再次被调用,导致递归不断循环,因此 StackOverflowError .

    我建议您创建一个计数器来限制最大尝试次数。 对于这个用例,从这个问题中得到启发 How do you implement a re-try-catch?

    有许多库提供恢复机制。我向你推荐 jcabi-aspects .

        3
  •  3
  •   L.Spillner    7 年前

    它不会“恢复”它,而是重新开始并重试。这可能导致无休止的递归调用循环,直到发生stackoverflow。在这种情况下,您的应用程序将被停止。

    想象一下访问一个不存在的文件(由于打字错误或其他原因)。你总是能抓住 FileNotFoundException 一次又一次地尝试读取同一个不存在的文件…

    在不改变任何东西的情况下一次又一次地重新开始相同的任务,几乎总是会导致相同的异常,并且发生上述情况。正确的异常处理总是比在任何情况下保持程序的活动性更重要。让软件的用户知道问题所在。也许这是他可以改变的。也许不是。无论如何,最好中止线程,而不是递归地重新开始。