2016-07-29 17 views
1

Ich verstehe nicht, die Protokolle aus dem folgenden Codeabschnitt:java: Thread-Verhalten von ReentrantLock Verhalten angezeigt

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

Wenn alles gut ausgeführt wird, wird der Protokolleintrag wie folgt:

[INFO] 2016-07-29 09: 58: 59,163: PersistenceThread.getInfoBox (PersistenceThread.java:618) PersistenceThread getInfoBox, das Informationsfeld an C: \ Users \ jake_000_filedump_infoBoxes \ AccountExecutive1469777154904.xml

erhält

[INFO] 2016.07.29 09: 58: 59.179: PersistenceThread.getInfoBox (PersistenceThread.java:620) PersistenceThread getInfoBox bekam lockC: \ Benutzer \ jake_000_filedump_infoBoxes \ AccountExecutive1469777154904.xml

[INFO] 2016-07- 29 09: 58: 59.203: PersistenceThread.getInfoBox (PersistenceThread.java:627) PersistenceThread getInfoBox bekam Info-Box

[INFO] 2016.07.29 09: 58: 59.207: PersistenceThread.getInfoBox (PersistenceThread.java:639) PersistenceThread getInfoBox freigegeben Sperre

aber ich ha ve eine seltsame Anomalie

[INFO] 2016.07.29 09: 59: 16.079: PersistenceThread.getInfoBox (PersistenceThread.java:618) PersistenceThread getInfoBox bekommen Info-Box unter C: \ Benutzer \ jake_000_filedump_infoBoxes \ AccountExecutive1469778628407 .xml

[INFO] 2016.07.29 09: 59: 16.084: PersistenceThread.getInfoBox (PersistenceThread.java:620) PersistenceThread getInfoBox bekam lockC: \ Benutzer \ jake_000_filedump_infoBoxes \ AccountExecutive1469778628407.xml

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

HINWEIS Obwohl das Schloss erworben, Die InfoBox nicht abgerufen wird Eine Ausnahme ist NICHT Geworfen ABER die Sperre später 1 Minute FREIGEGEBEN.

Kann mir jemand die zugrunde liegenden Prozesse erklären, die dies zulassen?

Schließlich ist die Anomalie im Protokoll (oben) die letzte Zeile der Protokolldatei. Danach scheint der Thread komplett aufgehängt zu sein.

+5

Was ist in der Methode passiert, die 'getInfoBox()' aufgerufen hat? Weil ein 'Error'-Throwable nicht von diesem Exception-Handler abgefangen würde und den Thread abstürzen würde. (Vielleicht war es ein StackOverflowError oder OutOfMemoryError) – Kiskae

+1

Ein kurzer Kommentar (und das ist wahrscheinlich nicht die Ursache Ihres Problems), aber Sie sollten die Zeilen wahrscheinlich über den 'try'-Aufruf hinaus auf den' lock.lock() 'Aufruf verschieben 'block - Wenn Sie aus irgendeinem Grund vor dem Aufruf von' lock.lock() 'eine Ausnahme auslösen und Ihr' finally' Block versucht, sie zu entsperren, werfen Sie eine zusätzliche 'IllegalMonitorStateException'. – CodeBlind

+0

@Kiskae, danke. Ich protokolliere JVM-Speicher. Es gibt keine Speicherprobleme (Gigs zu ersparen). Trotzdem bist du vielleicht auf etwas! Ich werde meine Ausnahmebehandlung überprüfen. – Jake

Antwort

1

Aus den Kommentaren:

Wie Sie es erklärt nicht alle Aussagen im try Block beendet haben und haben die catch Block nicht ausgeführt werden. Dies bedeutet wahrscheinlich, dass etwas geworfen wurde, das kein Exception -Klassenfehler war, wie zum Beispiel ein StackOverflowError, AssertionError oder OutOfMemoryError. Wenn die Anwendung nicht abstürzte und es keine Protokolle gab, dann wurde die Error wahrscheinlich irgendwo in der Anwendung verschluckt, was das Debugging sehr schwierig macht.

+0

Ich versuche jetzt (Error err) am Ende jeder Thread-Methode zu fangen. Ist dies der am besten geeignete Ort, um Fehler in einer Multithread-Anwendung zu erfassen? – Jake

+1

Sie sollten wahrscheinlich keine Fehler erfassen, da sie normalerweise nicht wiederherstellbar sind. Die Protokollierung von unerwarteten Ausnahmen sollte über die 'Thread.setUncaughtExceptionHandler (...)' Methode erfolgen. Setzen Sie einfach einen Handler, bevor Sie mit der Arbeit im Thread beginnen. – Kiskae

+0

Gotcha ..... obwohl ich den Fehler einmal nachgemeldet habe ... vergessen zu erwähnen – Jake