Frage

Wie kann ich programmatisch erkennt, dass ein Deadlock in einem Java-Programm aufgetreten ist?

Keine korrekte Lösung

Andere Tipps

Sie können dies tun programmatisch die ThreadMXBean, das mit dem JDK:

ThreadMXBean bean = ManagementFactory.getThreadMXBean();
long[] threadIds = bean.findDeadlockedThreads(); // Returns null if no threads are deadlocked.

if (threadIds != null) {
    ThreadInfo[] infos = bean.getThreadInfo(threadIds);

    for (ThreadInfo info : infos) {
        StackTraceElement[] stack = info.getStackTrace();
        // Log or store stack trace information.
    }
}

Natürlich sollten Sie versuchen, zu isolieren, je nachdem, welchen Thread diese Deadlock-Prüfung durchführt - Andernfalls, wenn dieser Thread Deadlocks wird es nicht möglich sein, um die Prüfung laufen

Im übrigen ist es das, was JConsole ist unter der Decke verwendet wird.

Ein nützlicher Hinweis für die Untersuchung:

Wenn Sie die Anwendung fangen rot handed und vermuten, dass ein Deadlock aufgetreten ist, gehen und drücken Sie „Strg-Break“ in dem java.exe Konsolenfenster (oder „Strg- \“ auf Solaris / Linux). Die JVM wird den aktuellen Status und Stack-Trace aller Threads Dump, Riegelschlösser herausfinden und sie genau beschreiben.

Es wird wie folgt aussehen:

Full thread dump Java HotSpot(TM) Client VM (1.5.0_09-b03 mixed mode):

"[Test Timer] Request Queue" prio=6 tid=0x13d708d0 nid=0x1ec in Object.
    wait() [0x1b00f000..0x1b00fb68]
    at java.lang.Object.wait(Native Method)
    at java.lang.Object.wait(Unknown Source)
    at library.util.AsyncQueue.run(AsyncQueue.java:138)
        - locked <0x02e70000> (a test.server.scheduler.SchedulerRequestQueue)

    ...

Found one Java-level deadlock:
=============================
"Corba service":
  waiting to lock monitor 0x13c06684 (object 0x04697d90, a java.lang.Object),
  which is held by "[Server Connection] Heartbeat Timer"
"[Server Connection] Heartbeat Timer":
  waiting to lock monitor 0x13c065c4 (object 0x0467e728, a test.proxy.ServerProxy), which is held by "Corba service"

Java stack information for the threads listed above:
===================================================
"Corba service":
    at test.proxy.ServerProxy.stopHBWatchDog(ServerProxy:695)
    - waiting to lock <0x04697d90> (a java.lang.Object)
    ...

Sie können die Deadlock-Threads erkennen programmatisch mit ThreadMXBean class.Here der Code ist,

    ThreadMXBean bean = ManagementFactory.getThreadMXBean();

    long ids[] = bean.findMonitorDeadlockedThreads();

    if(ids != null)
    {
        ThreadInfo threadInfo[] = bean.getThreadInfo(ids);

        for (ThreadInfo threadInfo1 : threadInfo)
        {
            System.out.println(threadInfo1.getThreadId());    //Prints the ID of deadlocked thread

            System.out.println(threadInfo1.getThreadName());  //Prints the name of deadlocked thread

            System.out.println(threadInfo1.getLockName());    //Prints the string representation of an object for which thread has entered into deadlock.

            System.out.println(threadInfo1.getLockOwnerId());  //Prints the ID of thread which currently owns the object lock

            System.out.println(threadInfo1.getLockOwnerName());  //Prints name of the thread which currently owns the object lock.
        }
    }
    else
    {
        System.out.println("No Deadlocked Threads");
    }

Klicken Sie auf hier für weitere Informationen darüber, wie zu erkennen die Deadlock-Threads.

JArmus ist eine Bibliothek zur Deadlock-Erkennung und Vermeidung. Es bietet Unterstützung für: Thread.join, CyclicBarrier, CountDownLatch, Phaser und ReentrantLock.

Um JArmus verwenden Sie müssen Ihren Code Instrument. Entweder durch eine seiner instrumentierten Klassen oder automatisch mit dem JArmus instrumentar jarmusc.

java -jar jarmusc.jar yourprogram.jar checkedprogram.jar

Der Eingang yourprogram.jar ist das Programm, das Sie überprüfen möchten. Der Ausgang ist das gleiche Programm mit überprüft automatisch alle Sackgassen zu finden.

Schranken brauchen Hilfe

Überprüfen Deadlocks mit Klassen CyclicBarrier, CountDownLatch, Phaser ist ein bisschen schwierig --- zum Beispiel JConsole können diese Arten von Deadlocks nicht erkennen. JArmus braucht ein wenig Hilfe von Ihnen: Sie müssen angeben, welche Threads Synchronisation beeinflussen, nennen wir diese registriert Themen.

So bald wie möglich, muss der Faden selbst markiert als registriert. Ein guter Platz zum registrierten Gewinde Markierung wird am Anfang Methode Runnable.run. JArmus.register(latch);

Beispiel

Das folgende Programm, das korrekt identifiziert Deadlocks durch JArmus:

final CountDownLatch latch = new CountDownLatch(2);
final CyclicBarrier barrier = new CyclicBarrier(2);
final Queue<Exception> exceptions = new ArrayDeque<>();
Thread t1 = new Thread(new Runnable() {
    @Override
    public void run() {
        try {
            JArmus.register(barrier); // do not forget to register!
            JArmus.register(latch); // do not forget to register!
            latch.countDown();
            latch.await();
            barrier.await();
        } catch (Exception e) {
            exceptions.add(e);
        }
    }
});
Thread t2 = new Thread(new Runnable() {
    @Override
    public void run() {
        try {
            JArmus.register(barrier); // do not forget to register!
            JArmus.register(latch); // do not forget to register!
            barrier.await();
            latch.countDown();
            latch.await();
        } catch (Exception e) {
            exceptions.add(e);
        }
    }
});
t1.start();
t2.start();

Sie können IBMs MTRAT zu betrachten. Vorbeugen ist besser als heilen, nachdem alle. Der Multicore- Software Development Kit auch mit einem Deadlock-Erkennung Werkzeug kommt.

Wenn Sie keine programmatische Erkennung benötigen Sie können dies tun, über die JConsole ; auf dem Gewinde Register gibt es einen „toten Punkt erfassen“ -Taste. In JDK6 erkennen diese Sperren für beide intrinsische Monitore und j.u.c Locks

Führen Sie den JConsole über den $JAVA_HOM/bin/jconsole Befehl up

Es gibt Code hier: http://www.java2s.com /Code/Java/Development-Class/PerformingdeadlockdetectionprogrammaticallywithintheapplicationusingthejavalangmanagementAPI.htm

Die Magie geschieht in ThreadMonitor.findDeadlock():

  public boolean findDeadlock() {
    long[] tids;
    if (findDeadlocksMethodName.equals("findDeadlockedThreads")
        && tmbean.isSynchronizerUsageSupported()) {
      tids = tmbean.findDeadlockedThreads();
      if (tids == null) {
        return false;
      }

      System.out.println("Deadlock found :-");
      ThreadInfo[] infos = tmbean.getThreadInfo(tids, true, true);
      for (ThreadInfo ti : infos) {
        printThreadInfo(ti);
        printLockInfo(ti.getLockedSynchronizers());
        System.out.println();
      }
    } else {
      tids = tmbean.findMonitorDeadlockedThreads();
      if (tids == null) {
        return false;
      }
      ThreadInfo[] infos = tmbean.getThreadInfo(tids, Integer.MAX_VALUE);
      for (ThreadInfo ti : infos) {
        // print thread information
        printThreadInfo(ti);
      }
    }

    return true;
  }

Dies erfordert eine API des ThreadMXBean, die in Java 5 und 6 (daher der äußere if()).

einen anderen Namen hat

Das Codebeispiel ermöglicht auch die Sperren zu unterbrechen, so kann man sogar den Stillstand brechen.

tempus fugit- setzt sie auch zusammen mit einer programmatischen Faden Dumping Klasse. Es implementiert den mbean Mechanismus oben erwähnt, und bietet einen Tropfen in, out-of-the-box-Super-Duper-Lösung.

Falls Sie es möchten in der Laufzeit durchgeführt werden können Sie mit Watchdog das.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top