防止在Java中退出运行时异常的循环

时间:2016-02-21 17:40:07

标签: java exception design-patterns

我有服务,我希望它有以下行为:

  1. 如果服务收到InterruptedException,或者JVM关闭,它应该尝试优雅地停止
  2. 如果有一些“灾难性”事件,该服务应该退出
  3. 应记录任何其他异常,状态应重置,循环应继续运行
  4. 在任何其他情况下,循环都不应该退出。
  5. 所以这是我提出的过于简化的版本。

    在课堂上:

    private static volatile boolean keepRunning = true;
    
    static {
        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                keepRunning = false;
            }
        }); 
    }
    

    然后循环:

    while(keepRunning) {
        try {
            // Do something useful
            Thread.sleep(10000); // just an example of something that can cause InterruptedException 
        }
        catch(InterruptedException e) { 
            keepRunning = false;
        }
        catch(Exception e) { // catches all exceptions, but not any errors
            // log it
            // reset state
        }
    }
    if(!keepRunning) {
        // shut down gracefully
    }
    

    似乎满足所有4个条件,但存在一些问题和不清楚的部分:

    1. (问题)抓住Exception而不做任何事情是违反所有良好做法的。但在这种情况下是否可以接受,或者有更好的解决方案?
    2. (问题)捕捉Error我需要做些什么来满足条件#2?或者还有其他我应该注意的情况吗?
    3. (不清楚)通常建议在异常后“关闭优雅”代码进入finally部分,我真的不喜欢我必须在循环后检查它(if(!keepRunning)) 。但在这种情况下似乎不适合finally。有没有更好的方法呢?
    4. (问题)此代码是为Java 7编写的。是否可以使用Java 8更改/改进任何内容?
    5. 我将非常感谢我对问题的直接回答,或对不同模式/解决方案的指示。提前谢谢。

1 个答案:

答案 0 :(得分:2)

可以在你的案例中抓住Exception

如果你运行测试,不捕捉Error是一个很好的做法。

finally块是您应该用来优雅地关闭的块,是的 - if块中的finally语句是必需的,一般都可以。

如果发生错误,您的finally块仍将执行,因此一切正常。

此代码适用于Java 7和Java 8