2015-06-19 102 views
3

根據我的理解,我想遵循最終釋放資源的最佳做法,以防止任何連接泄漏。這是我在HelperClass中的代碼。java中的try-catch-finally塊

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; 
} 

我的疑問是,因爲最後塊將被無論什麼時候,會把dynamoDB返回空連接,因爲它會在最後被關閉,然後執行語句執行? TIA。

+2

當你嘗試時發生了什麼? –

+3

在調用dynamoDB.shutdown()之前,最好在dynamoDB上做一個空的檢查。 – paramupk

+0

無論異常是否發生,dynamoDB都會關閉。只有在它被使用後纔會關閉。如果你只想連接,爲什麼你甚至需要關閉它,因爲如果出現錯誤,你將不會有連接並拋出null指針異常,如果你得到一個連接,你爲什麼要關閉? – geddamsatish

回答

8

你的理解是正確的。 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 
} 
+0

非常感謝。我必須在這裏學習,我不必擔心在我獲得它的地方釋放連接。 (也就是說,在我的情況下,它是來自助手類調用,公共靜態DynamoDB getDynamoDBConnection()。但是我必須擔心在我實際使用它的地方關閉連接,非常感謝。 – Chandz

1

是的,dynamoDB將返回一個空連接,因爲dynamoBD.shutdow()將在return語句Always中執行。

+0

非常感謝 – Chandz

0

我們如何「模仿」錯誤並查看會發生什麼?這就是我的意思是:

___Case 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"); 
    } 

___Case 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,這將幫助你更容易地編寫這樣的測試。

1

儘管我沒有回答你總是執行finally塊的問題(這個問題已經有好幾個答案了),但我想分享一些關於如何使用DynamoDB客戶端的信息。

DynamoDB客戶端是一個線程安全的對象,旨在在多個線程之間共享 - 您可以爲應用程序創建一個全局對象,並在需要時重新使用該對象。通常,客戶端創建是由某種IoC容器(例如Spring IoC容器)管理的,然後由容器通過依賴注入提供給任何需要的代碼。

在底層,DynamoDB客戶端維護一個HTTP連接池,用於傳遞DynamoDB端點並使用此池中的連接。在構建客戶端時,可以通過傳遞ClientConfiguration對象的實例來配置池的各種參數。例如,其中一個參數是允許的最大打開HTTP連接數。

有了上述理解,我會說由於DynamoDB客戶端管理HTTP連接的生命週期,因此資源泄漏應該不是真正關注使用DynamoDB客戶端的代碼。