2012-06-28 5 views
5

Die JVM mir sagt, dass ein Deadlock aufgetreten ist:„Gefunden 1 Deadlock“, aber Spur zeigt, dass nicht von einem Thread gesperrt

Found one Java-level deadlock: 
============================= 
"TP-Processor107": 
    waiting for ownable synchronizer 0x00002aaaf58e70f0, (a java.util.concurrent.locks.ReentrantReadWriteLock$NonfairSync), 
    which is held by "indexTrackerThread3" 
"indexTrackerThread3": 
    waiting for ownable synchronizer 0x00002aaaf4394580, (a java.util.concurrent.locks.ReentrantReadWriteLock$NonfairSync), 
    which is held by "TP-Processor16" 
"TP-Processor16": 
    waiting for ownable synchronizer 0x00002aaaf58e70f0, (a java.util.concurrent.locks.ReentrantReadWriteLock$NonfairSync), 
    which is held by "indexTrackerThread3" 

Wir können sehen, dass indexTrackerThread3 für eine Ressource von TP-Processor16 gehalten warten, und vice -versa. Das ist in der Tat eine Sackgasse.

Wir können sehen, dass indexTrackerThread3 wartet auf 0x00002aaaf4394580:

"indexTrackerThread3": 
    - parking to wait for <0x00002aaaf4394580> 

Meine Frage:

In the threads dump, warum gibt es keine Linie - locked <0x00002aaaf4394580>?

Es scheint wie 0x00002aaaf58e70f0 ist eigentlich nicht durch einen Thread gesperrt. Was könnte es sperren?

In allen Deadlock-Dokumentation habe ich gelesen (example), für jede andere - parking to wait for <0x123> Zeile gibt es immer eine - locked <0x123> Zeile. Ich beginne also einen JVM-Bug zu vermuten. Versteh ich etwas falsch?

Hinweis: Entschuldigung für die Verbindung zu Pastebin, aber die Frage ist nicht zu verantworten, ohne die vollständige Dump. Der Kürze halber entfernte ich alle Zeilen, die "at" enthielten, sie enthielten keine Sperrinformationen.

Antwort

4

Das java.util.concurrent-Paket verwendet einen extralingualen nativen Parkmechanismus (sowie andere native Mechanismen wie einen atomaren Compare-and-Swap). Du kannst sehen, wovon ich rede here.

Das Muster, das Sie normalerweise im Thread Dump beschreiben, stammt vom klassischen Java-Idiom synchronized(lock) { lock.wait(); }.

+0

Danke für den Link! Ich habe mich jetzt mit der unsicheren Klasse vertraut gemacht. Selbst wenn sie über einen Aufruf von Unsafe.park ausgeführt werden, kommt die Sperrung immer noch von einem Java-Aufruf. Warum also sollte der "locked <0x123>" -Teil nicht in dieser Zeile geschrieben sein? Ich würde mich über jede Dokumentation freuen, die über das besondere Problem spricht, dass ich nicht anwesend bin. –

0

Marko Topolniks Antwort ist korrekt.

Zur Lösung Ihres Problems zeigt JProfiler ein vollständiges Diagramm mit Threads und Monitoren für Sperrsituationen, die Sperren aus dem Paket java.util.concurrent enthalten.

Haftungsausschluss: Meine Firma entwickelt JProfiler

0

Verschiedene Dinge können Java-Threads, Monitore, auch bekannt als die synchronisierte Schlüsselwort, sind nur eine Sache, eine Sackgasse.

A lock can be a built-in object monitor, an ownable synchronizer, or the Condition object associated with synchronizers.

Sie können auch in den Definitionen von ThreadMXBean.findDeadlockedThreads und ThreadMXBean.findMonitorDeadlockedThreads um weitere Informationen graben.

Soweit es mich betrifft, ist es die Monitorverriegelung und die Java 5 Verriegelung.

In Thread-Dumps ist die Kombination waiting to lock <0x123> und locked <0x123> nur für die Bildschirmsperre vorgesehen. Mit Java 5 Locking erhalten Sie nur den ersten Teil. So etwas wie parking to wait for <0x456>. Sie suchen dann nach 0x456 im Thread-Dump, aber es ist nirgendwo zu finden. Das ist verwirrend.

0

Die Komplexität der Thread-Dump-Analyse für einen solchen Deadlock ist hauptsächlich auf die Verwendung des Pakets java.util.concurrent zurückzuführen. Dies wurde entwickelt, um von der klassischen und intrusiven Art der Synchronisation von Java-Objekten wegzukommen. Dieses Paket ist sehr nützlich, wenn Sie beispielsweise die WRITE-Operationen auf ein einzelnes Thread-Modell beschränken und gleichzeitig READ-Operationen zulassen möchten. Dieser Ansatz ist im Hinblick auf die Leistungsoptimierung von Vorteil, der Nebeneffekt ist eine erhöhte Komplexität des Thread Dump-Analyseprozesses bei der Behandlung von Nebenläufigkeitsproblemen.

Ich schlage vor, dass Sie auch den folgenden Artikel lesen. Es beschreibt Probleme wie hidden Java deadlock Szenarien, in denen die JVM nicht einmal in der Lage ist, den Deadlock zu erkennen (aufgrund von READ-Sperren, die normalerweise keine Eigentumsrechte haben). Beispiel-Java-Programm wird als ein Beispiel bereitgestellt.

0

Der Stack-Trace zeigt, dass 0x00002aaaf4394580 nicht durch einen Thread gesperrt ist. Dies kann aufgrund Java bug #6822370 auftreten. Diese Beobachtung sollte der voted answer einen Abschluss hinzufügen.