2010-09-17 10 views
9

Ich habe eine Multithread-Anwendung. Mehrere Nachrichten kommen zur Anwendung und werden in getrennten Threads verarbeitet. Dazu verwende ich die Klassen ThreadPoolExecutor und FutureTask aus dem Paket java.util.concurrent.Wie Stack-Spur eines Threads erhalten

Gelegentlich habe ich einige Deadlocks in der Anwendung. Wenn ein Deadlock auftritt, möchte ich den blockierenden Thread unterbrechen, und ich möchte den Stack-Trace dieses Threads protokollieren, damit ich den Deadlock später auflösen kann.

Gibt es eine Möglichkeit, wie können wir den Stack-Trace eines Threads außerhalb dieses Threads in Java finden?

+0

Sie meinen, Sie wollen Deadlock erkennen und wiederherstellen? Niemals getan, aber eine Stack-Trace für das klingt nicht wie der richtige Weg zu mir .. –

+0

Ich brauche die Stack-Trace, so dass ich weiß, wo der Thread stecken und kann das Problem beheben, so dass die Anwendung ganz danach funktioniert Neustart. Jedoch möchte ich den blockierenden Thread unterbrechen, damit die Anwendung funktioniert, bis ich etwas Zeit finde, das Problem zu beheben und es freizugeben. – Palo

Antwort

5

Siehe auch here für das Generieren von Stack-Traces, einschließlich der programmatischen Vorgehensweise. Von der Konsole wird Ctrl + Break die Stack-Traces auf stdout ausgeben. Siehe auch this SO question für weitere Details.

+5

In UNIX-Umgebungen wird durch das Senden eines "QUIT" ('kill -QUIT ') Signals an den Java-Prozess auch der Stack-Trace an die Standardausgabe ausgegeben. – Bombe

5

Sie könnten die Stack-Traces aller Threads von Zeit zu Zeit (oder vor dem Beenden des Prozesses) in Ihrer Anwendung protokollieren. Um dies zu tun:

Map<Thread, StackTraceElement[]> m = Thread.getAllStackTraces(); 
for(Map.Entry<Thread, StackTraceElement[]> e : m.entrySet()) { 
    log(e.getKey().toString()); 
    for (StackTraceElement s : e.getValue()) { 
     log(" " + s); 
    } 
} 

Wenn nächtliche automatisierte Tests ausgeführt werden, kommt manchmal einer der Testfälle in eine Sackgasse. Ich habe einen "TimeBomb" -Daemon-Thread hinzugefügt, der 30 Minuten wartet und dann alle Stack-Traces wie oben protokolliert.

0

war ich nicht sicher, ob Sie die Stacktrace innerhalb derselben JVM oder extern erhalten wollen, aber wenn Sie den Stack-Trace mit externen Tools erhalten möchten, wird folgendes helfen:

  • The Java VisualVM Werkzeug kann verwendet werden, um eine Verbindung zur laufenden JVM herzustellen, in der der Thread-Stack abgelegt werden kann. Dies ist normalerweise der bevorzugte Ansatz für die meisten Benutzer von Java 6. Nach dem Start von VisualVM kann der Thread-Dump des Prozesses abgerufen werden, indem der Prozess auf der Registerkarte Anwendung ausgewählt wird. Eine Registerkarte "Threads" wird nun zur Verfügung gestellt, um die Threads im laufenden Prozess anzuzeigen. Auf der gleichen Registerkarte finden Sie die Schaltfläche "Thread Dump", um die erforderlichen Informationen zu extrahieren.
  • Das Dienstprogramm jstack innerhalb des JDK kann auch verwendet werden, um Thread-Stacktraces zu erzeugen.
2

Sie verwenden JStack. Hier ist eine nette blog entry, die Details, wie Sie Stack-Spuren erhalten.

4

Vor der Sackgasse Bereich eintritt, setzen Sie ein Feld wie,

thread = Thread.currentThread(); 

In Ihrem Monitor-Thread Sie thread.getStackTrace(); ausführen können den Stack-Trace von diesem Thread zu jeder Zeit zu bekommen.

0

Wenn ein Deadlock auftritt ich den Sperr Thread zu unterbrechen will ...

Sie eine periodische Aufgabe für Deadlocks zu überprüfen implementieren könnte und Call (wo Deadlocks java intrinsische oder Lock basieren) interrupt für alle Threads, die am Szenario beteiligt sind. Dies hat jedoch keine Garantie, dass es Ihr Problem löst. Es ist wahrscheinlich das Szenario, das gerade wieder passieren wird. Details finden Sie unter Dr Heinz's article on a deadlock detector.

Wenn es tatsächlich gibt, gibt es keine Garantie, dass interrupt sogar einen blockierten Prozess wie diesen freigeben wird. Es ist ein weitaus besserer Ansatz, um das Deadlock-Szenario zu vermeiden, indem beispielsweise Locks mit Timeouts und Retry-Strategien oder "Try Before You Buy" -Ansätze verwendet werden.

und ich möchte den Stack-Trace diesen Thread log ...

Wenn Sie dies programmatisch wieder tun wollen, Dr. Heinz Beispiel folgen. Wenn nicht, generieren Sie einfach den Thread-Dump, wenn Sie das Problem erkannt haben.

Gibt es eine Möglichkeit, wie können wir die Stack-Ablaufverfolgung eines Threads außerhalb dieses Threads in Java finden?

Ja und nein. Sie können die Threads von anderen VMs ablegen, aber ihre Stack-Traces sind möglicherweise nicht so nützlich, wie Sie vielleicht denken, um die Ursachen für Ihren Deadlock zu ermitteln. Wenn ein echter Deadlock erkannt wurde (von der JVM selbst auf dem Thread-Dump von Ihre Anwendungen VM) sollten Sie alles, was Sie benötigen, um die Ursache (mehr oder weniger) zu debuggen.