【问题标题】:try-catch-finally block in javajava中的try-catch-finally块
【发布时间】:2015-09-05 08:19:45
【问题描述】:

据我了解,我想遵循最终释放资源的最佳做法,以防止任何连接泄漏。这是我在 HelperClass 中的代码。

public static DynamoDB getDynamoDBConnection()
{   
    try
    {
        dynamoDB = new DynamoDB(new AmazonDynamoDBClient(new ProfileCredentialsProvider()));
    }
    catch(AmazonServiceException ase)
    {
        //ase.printStackTrace();
        slf4jLogger.error(ase.getMessage());
        slf4jLogger.error(ase.getStackTrace());
        slf4jLogger.error(ase);
    }
    catch (Exception e)
    {
        slf4jLogger.error(e);
        slf4jLogger.error(e.getStackTrace());
        slf4jLogger.error(e.getMessage());
    }
    finally
    {
        dynamoDB.shutdown();
    }
    return dynamoDB;
}

我的疑问是,由于无论如何都会执行 finally 块,dynamoDB 是否会返回空连接,因为它将在 finally 块中关闭,然后执行return 声明? TIA。

【问题讨论】:

  • 当你尝试它会发生什么?
  • 最好在调用 dynamoDB.shutdown() 之前对 dynamoDB 进行空检查;
  • dynamoDB 无论是否发生异常都会关闭。您只在使用后关闭。如果您只想要连接,为什么您甚至需要关闭它,因为如果您将没有连接出现问题并引发空指针异常,如果您获得连接,为什么要关闭?
  • @aioobe 请原谅我的延迟回复。这些天来,我被调到另一个项目中,没有机会从事这个项目。您的回答非常有帮助和赞赏。非常感谢。 :+1

标签: java amazon-dynamodb try-catch-finally program-flow


【解决方案1】:

你的理解是正确的。 dynamoBD.shutdown() 将始终在 return dynamoDB 之前执行。

我不熟悉您正在使用的框架,但我可能会按如下方式组织代码:

public static DynamoDB getDynamoDBConnection()
        throws ApplicationSpecificException {   
    try {
        return new DynamoDB(new AmazonDynamoDBClient(
                                    new ProfileCredentialsProvider()));
    } catch(AmazonServiceException ase) {
        slf4jLogger.error(ase.getMessage());
        slf4jLogger.error(ase.getStackTrace());
        slf4jLogger.error(ase);
        throw new ApplicationSpecificException("some good message", ase);
    }
}

并将其用作

DynamoDB con = null;
try {
    con = getDynamoDBConnection();
    // Do whatever you need to do with con
} catch (ApplicationSpecificException e) {
    // deal with it gracefully
} finally {
    if (con != null)
        con.shutdown();
}

您还可以为您的 dynamoDB 连接创建一个 AutoCloseable 包装器(在 close 内调用 shutdown)并执行

try (DynamoDB con = getDynamoDBConnection()) {
    // Do whatever you need to do with con
} catch (ApplicationSpecificException e) {
    // deal with it gracefully
}

【讨论】:

  • 非常感谢。我必须在这里学习,我不必担心在我得到它的地方释放连接。 (即,在我的情况下,它来自辅助类调用,公共静态 DynamoDB getDynamoDBConnection()。但我必须担心在我实际使用它的地方关闭连接。非常感谢。
【解决方案2】:

虽然我没有回答您关于始终执行 finally 块的问题(该问题已有多个答案),但我想分享一些有关如何使用 DynamoDB 客户端的信息。

DynamoDB 客户端是一个线程安全的对象,旨在在多个线程之间共享 - 您可以为您的应用程序创建一个全局对象,并在需要时重新使用该对象。通常,客户端创建由某种 IoC 容器(例如 Spring IoC 容器)管理,然后由容器通过依赖注入提供给任何需要它的代码。

在底层,DynamoDB 客户端维护一个 HTTP 连接池,用于与 DynamoDB 终端节点进行通信,并使用来自该池的连接。在构造客户端时,可以通过传递ClientConfiguration对象的实例来配置池的各种参数。例如,参数之一是允许打开的 HTTP 连接的最大数量。

基于上述理解,我想说,由于 DynamoDB 客户端管理 HTTP 连接的生命周期,因此使用 DynamoDB 客户端的代码不应该真正担心资源泄漏。

【讨论】:

    【解决方案3】:

    是的,dynamoDB 将返回一个空连接,因为 dynamoBD.shutdow() 将在 return 语句之前执行,始终。

    【讨论】:

      【解决方案4】:

      我们如何“模仿”错误并看看会发生什么?这就是我的意思:

      ___案例 1___

      try{
        // dynamoDB = new DynamoDB(new AmazonDynamoDBClient(new ProfileCredentialsProvider()));
        throw new AmazonServiceException("Whatever parameters required to instantiate this exception");
      }    catch(AmazonServiceException ase)
          {
              //ase.printStackTrace();
              slf4jLogger.error(ase.getMessage());
              slf4jLogger.error(ase.getStackTrace());
              slf4jLogger.error(ase);
      
          }
          catch (Exception e)
          {
              slf4jLogger.error(e);
              slf4jLogger.error(e.getStackTrace());
              slf4jLogger.error(e.getMessage());
          }
          finally
          {
              //dynamoDB.shutdown();
              slf4jLogger.info("Database gracefully shutdowned");
          }
      

      ___案例 2___

      try{
        // dynamoDB = new DynamoDB(new AmazonDynamoDBClient(new ProfileCredentialsProvider()));
        throw new Exception("Whatever parameters required to instantiate this exception");
      }    catch(AmazonServiceException ase)
          {
              //ase.printStackTrace();
              slf4jLogger.error(ase.getMessage());
              slf4jLogger.error(ase.getStackTrace());
              slf4jLogger.error(ase);
      
          }
          catch (Exception e)
          {
              slf4jLogger.error(e);
              slf4jLogger.error(e.getStackTrace());
              slf4jLogger.error(e.getMessage());
          }
          finally
          {
              //dynamoDB.shutdown();
              slf4jLogger.info("Database gracefully shutdowned");
          }
      

      这些练习可能是使用单元测试的理想场所,更具体地说是mock tests。我建议您仔细查看JMockit,它会帮助您更轻松地编写此类测试。

      【讨论】:

        猜你喜欢
        • 2011-06-01
        • 2011-10-31
        • 2011-11-17
        • 2013-12-16
        • 2011-08-31
        • 1970-01-01
        • 2012-03-06
        • 2014-11-27
        • 1970-01-01
        相关资源
        最近更新 更多