2016-07-29 54 views
1

我不從下面的代碼段理解日誌:Java語言:ReentrantLock的行爲表示線程行爲

private InfoBox getInfoBox(Path p) 
{ 

    try 
    { 

     String path = p.toString(); 
     Log.getLogger().info("getting info box at " + path); 
     lock.lock(); 
     Log.getLogger().info("got lock" + path); 

     JAXBContext jaxbContext = JAXBContext.newInstance(InfoBox.class); 

     Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); 
     InfoBox ib = (InfoBox) jaxbUnmarshaller.unmarshal(p.toFile()); 

     Log.getLogger().info("got info box"); 
     return ib; 
    } 
    catch (Exception e) 
    { 
     Log.getLogger().error(e.getMessage(), e); 
     return null; 

    } 
    finally 
    { 
     lock.unlock(); 
     Log.getLogger().info("released lock"); 
    } 
} 

當所有運行良好,日誌條目顯示如下:

[信息] 2016-07-29 09:58:59,163:PersistenceThread.getInfoBox(PersistenceThread.java:618)PersistenceThread getInfoBox獲取信息框在C:\ Users \ jake_000_filedump_infoBoxes \ AccountExecutive1469777154904.xml

[INFO] 2016年7月29日09:58:59179:PersistenceThread.getInfoBox(PersistenceThread.java:620)PersistenceThread getInfoBox得到lockC:\用戶\ jake_000_filedump_infoBoxes \ AccountExecutive1469777154904.xml

[INFO] 2016-07- 29 09:58:59,203:PersistenceThread.getInfoBox(PersistenceThread.java:627)PersistenceThread getInfoBox獲取信息框

[INFO] 2016-07-29 09:58:59,207:PersistenceThread.getInfoBox(PersistenceThread.java:639) PersistenceThread getInfoBox釋放鎖

但我公頃已經奇怪的異常

[INFO] 2016年7月29日09:59:16079:中C PersistenceThread.getInfoBox(PersistenceThread.java:618)PersistenceThread getInfoBox獲取信息框:\用戶\ jake_000_filedump_infoBoxes \ AccountExecutive1469778628407 .XML

[INFO] 2016年7月29日09:59:16084:PersistenceThread.getInfoBox(PersistenceThread.java:620)PersistenceThread getInfoBox得到lockC:\用戶\ jake_000_filedump_infoBoxes \ AccountExecutive1469778628407.xml

[INFO] 2016-07-29 10:01:36,926:PersistenceThread.getInfoBox(PersistenceThread.java:639)Per sistenceThread getInfoBox釋放鎖

雖然獲取鎖, 的資訊盒沒有檢索 一種不引發異常 BUT 鎖被釋放一分鐘後。

有人可以向我解釋允許這種情況發生的基本過程嗎?

最後,日誌(上面)中的異常是日誌文件的最後一行。之後,線程似乎完全掛起。

+5

在調用'getInfoBox()'的方法中發生了什麼?因爲'Error' throwable不會被該異常處理程序捕獲並導致線程崩潰。 (也許這是一個StackOverflowError或OutOfMemoryError) – Kiskae

+1

一個快速的評論(這可能不是你的問題的原因),但你應該將這些行移動到'try.lock()'調用上面'block - 如果因爲某種原因你在調用'lock.lock()'之前拋出一個異常,並且你的'finally'塊試圖解鎖它,你將會拋出額外的'IllegalMonitorStateException'。 – CodeBlind

+0

@Kiskae,謝謝。我正在記錄JVM內存。沒有內存問題(演出備用)。儘管如此,你還是可以做點什麼!我將檢查我的異常處理。 – Jake

回答

1

從評論:

正如你說,它並沒有完成所有的語句try塊中,並沒有執行catch塊。這可能意味着拋出了一些不是Exception級別的錯誤,例如StackOverflowError,AssertionErrorOutOfMemoryError。 如果應用程序沒有崩潰並且沒有日誌,那麼Error可能在應用程序的某個地方被悄悄地吞噬,這將使得這非常難以調試。

+0

我現在正試圖在每個線程運行方法結束時捕獲(錯誤錯誤)。這是在多線程應用程序中捕獲錯誤的最合適的地方嗎? – Jake

+1

你可能不應該捕捉錯誤,因爲它們通常是不可恢復的。記錄意外的異常應該通過'Thread.setUncaughtExceptionHandler(...)'方法完成。只需在線程開始工作之前設置一個處理程序。 – Kiskae

+0

gotcha .....雖然我沒有重新拋出一次記錄錯誤...忘了提及 – Jake