Advanced Java Services | Deadlock Detection |
Das JDK kommt mit einem nützlichen Tool namens JConsole mit dem man u.a. die laufenden Threads verfolgen kann und auch eine Prüfung auf Deadlocks vornehmen kann. Am einfachsten ist es, wenn man zuerst eine Javaanwendung startet und danach JConsole. In diesem Fall ermittelt JConsole beim Start automatisch die Prozess-ID der Anwendung. Startet man JConsole zuerst muß man den New Copnnection Dialog erst schließen und dann erneut öffnen. Das Tool befindet sich im bin-Verzeichnis des JDK und sieht nach dem Starten etwa wie folgt aus.
Man wählt eine Anwendung aus - in diesem Fall ImageViewer - und geht dann auf conect. Im Normalfall hat man für Standardapplikationen weder Username noch Passwort vergeben und bestätigt einfach mit Enter. Man bekommt dann zunächst eine Übersicht mit vier Graphiken.
Wählt man die Registerkarte Threads, so erhält man eine Übersicht über alle Threads, sowie einen Button zur Deadlockerkennung.
Weitere Information erhält man bei Oracle unter jconsole.html.
Seit der Version 1.4.1 gibt es in der Java Virtual Machine ein Utility, das Deadlocks aufspürt. Es wird mit Ctrl Pause (Windows) bzw. Ctrl \ (Linux, Solaris) von der Kommandozeile aus aktiviert. Das Utility entdeckt Deadlocks auf der Javaplattform, im Java Native Interface (JNI), im Java Virtual Machine Profiler Interface (JVMPI) und im Java Virtual Machine Debug Interface (JVMDI). Das Utility macht einen thread dump und gibt ihn auf die Konsole aus. Das Utility reagiert nicht auf Threads, die nur auf die Monitore warten.
Wie so ein Threaddump aussieht kann man hier sample-output.html lesen.
In Windows 7 läßt sich diese Utility nicht mehr mit Ctrl Pause aktivieren. es gibt jedoch eine Möglichkeit mit Hilfe der Klassen aus dem Package java.lang.management einen Deadlockdetector selbst zu schreiben. Startet man diesen Detector nach dem Eintreten eines Deadlocks, so werden einem die Threads ausgegeben, die diesen Deadlock verursachen. Hier ein ausbaufähiger Entwurf einer Klasse zur Entdeckung von Deadlocks.
import java.lang.management.ManagementFactory; import java.lang.management.ThreadInfo; import java.lang.management.ThreadMXBean; public class DeadLockDetector { private ThreadMXBean mxBean = ManagementFactory.getThreadMXBean(); private static DeadLockDetector instance = null; private DeadLockDetector() {}; public static DeadLockDetector getInstance() { if (instance==null) { instance = new DeadLockDetector(); return instance; } return instance; } public void detect() { long[] threadIds = mxBean.findDeadlockedThreads(); if (threadIds != null) { System.out.println("Deadlocks found : "); for(long l : threadIds) { ThreadInfo threadInfo = mxBean.getThreadInfo(l); //System.out.print(threadInfo); System.out.print(threadInfo.toString().substring(0, threadInfo.toString().length()-1)); } } else { System.out.println("No deadlocks found"); } } public ThreadMXBean getThreadMXBean() { return this.mxBean; } }
Siehe auch stackoverflow.com/questions/1102359/programmatic-deadlock-detection-in-java