Mehrere Java-threads scheinbar Verriegelung gleichen monitor?
In einer Java-threaddump ich Folgendes gefunden:
"TP-Processor184" daemon prio=10 tid=0x00007f2a7c056800 nid=0x47e7 waiting for monitor entry [0x00007f2a21278000]
java.lang.Thread.State: BLOCKED (on object monitor)
at org.apache.jackrabbit.core.state.SharedItemStateManager.getNonVirtualItemState(SharedItemStateManager.java:1725)
- locked <0x0000000682f99d98> (a org.apache.jackrabbit.core.state.SharedItemStateManager)
at org.apache.jackrabbit.core.state.SharedItemStateManager.getItemState(SharedItemStateManager.java:257)
"TP-Processor137" daemon prio=10 tid=0x00007f2a7c00f800 nid=0x4131 waiting for monitor entry [0x00007f2a1ace7000]
java.lang.Thread.State: BLOCKED (on object monitor)
at org.apache.jackrabbit.core.state.SharedItemStateManager.getNonVirtualItemState(SharedItemStateManager.java:1725)
- locked <0x0000000682f99d98> (a org.apache.jackrabbit.core.state.SharedItemStateManager)
at org.apache.jackrabbit.core.state.SharedItemStateManager.getItemState(SharedItemStateManager.java:257)
Der Punkt ist hier, dass beide threads gesperrt-monitor <0x0000000682f99d98> (unabhängig von Ihnen warten jetzt auf zwei verschiedenen Monitoren).
Wenn man bei der Thread-Dump-Analysator, mit diesem monitor wird ausgewählt, es ist wirklich sagt, "Threads sperren monitor: 2" an der Unterseite, und "2 Thread(s) sperren". Bitte sehen https://lh4.googleusercontent.com/-fCmlnohVqE0/T1D5lcPerZI/AAAAAAAAD2c/vAHcDiGOoMo/s971/locked_by_two_threads_3.png für den screenshot, ich bin nicht berechtigt, einfügen von Bildern hier.
Bedeutet dies threaddumps sind nicht atomic mit Respekt zu überwachen, Informationen zu sperren? Ich kann mir nicht vorstellen das wirklich ein schließ-Fehler der JVM (1.6.0_26-b03).
Eine ähnliche Frage wurde bereits gefragt, in Können mehrere threads die Sperre auf dem gleichen monitor in Java?, aber die Antwort mir nicht sehen, der eigentliche Punkt von mehreren threads sperren den gleichen monitor, obwohl Sie warten, für einen anderen.
Update Mai 13th 2014:
Neuere Frage Mehrere threads die gleiche Sperre? - code zum reproduzieren des Verhaltens und @rsxg angemeldet hat, einen entsprechenden bug-report https://bugs.openjdk.java.net/browse/JDK-8036823 entlang der Linien von seine Antwort hier.
- Keine Rückmeldung auf meine Antwort dude? Ich Schnitt ihn darauf hin, dass spätere Versionen des Codes haben eine
wait()
on line 1725. Akzeptieren Sie bitte, ob dies richtig ist. - Wir sind mit Jackrabbit version 1.6.5. Ein Freund von mir auch gesehen, dass
wait()
auf der gleichen Zeilennummer in der version 2.3.6, als es auffallend scheint zu passen, aber leider ist das die falsche sourcecode...
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sind Sie wahrscheinlich laufen in einen kosmetischen Fehler in der stack-trace-Routinen, die in der JVM bei der Analyse von stark umkämpften sperren - es kann oder kann nicht die gleiche sein, wie dieser Fehler.
Tatsache ist, dass keiner von den beiden threads haben es tatsächlich geschafft, die Sperre auf der
SharedItemStateManager
, wie Sie sehen können aus der Tatsache, dass Sie die Berichterstattungwaiting for monitor entry
. Der Fehler ist, dass weiter oben in der stack-trace in beiden Fällen sollte der Berichtwaiting to lock
stattlocked
.Den workaround bei der Analyse seltsam stack-traces wie dieses ist immer zu überprüfen, dass ein thread für sich beansprucht, ist
locked
ein Objekt ist nicht auch das warten auf das abrufen einer Sperre auf dem selben Objekt.(Leider ist diese Analyse erfordert die cross-verweisen auf die Zeilennummern in stack-trace, mit dem source code, da es keine Beziehung zwischen den Figuren in der
waiting for monitor entry
header und dielocked
Zeile in den stack-trace. Als pro diese Oracle-Dokument, die Anzahl0x00007f2a21278000
in der ZeileTP-Processor184" daemon prio=10 tid=0x00007f2a7c056800 nid=0x47e7 waiting for monitor entry [0x00007f2a21278000]
bezieht sich auf eine Schätzung der gültigen stack-region für den thread. So sieht es aus wie eine monitor-ID-ist es aber nicht - und Sie können sehen, dass die zwei Fäden, die Sie gegeben haben, sind an verschiedenen Adressen im stack).<0x0000000682f99d98>
), dass Sie warten, um zu erwerben, eine Sperre auf ([0x00007f2a21278000]
)?Ich glaube nicht, dass dein thread-dump ist zu sagen, dass Ihr zwei threads "warten auf zwei anderen Monitoren". Ich denke, es ist zu sagen, dass Sie warten beide auf den gleichen monitor aber bei zwei verschiedenen code-Punkte. Das könnte ein stack-Position oder ein Objekt Instanz Lage oder so etwas. Dies ist ein großartiges Dokument über die Analyse der Stapel dumps.
Nicht. Ihr stack dump zeigt zwei threads gesperrt, auf dem gleichen monitor mit dem gleichen code Ort, sondern in verschiedenen stack-frames -- oder was auch immer das Wert ist, das scheint OS abhängig.
Edit:
Ich bin mir nicht sicher, warum der thread-dump scheint zu sagen, dass beide threads eine Zeile gesperrt, da scheint nur zulässig, wenn Sie in einer
wait()
Methode. Ich bemerkte, dass Sie einen Link zu der version 1.6.5. Ist das wirklich die version, die Sie verwenden? In der version 2.3.6 (die neueste), die 1725 line ist eigentlich einwait
.Konnte man auch sehen diese Art der stack-trace, auch wenn es war eine exklusive
synchronized
sperren. Zum Beispiel, die folgende stack dump unter Linux ist für zwei threads gesperrt, die auf das gleiche Objekt aus der gleichen code-Zeile, sondern in zwei verschiedenen Instanzen desRunnable.run()
Methode. Hier ist meine dummes kleines test Programm. Beachten Sie, dass der monitor-Eintrag zahlen unterschiedlich sind, dachte sogar, es ist das gleiche, sperren und der gleichen code-Zeile, die Anzahl.Auf meinem Mac, das format ist anders, aber wieder der Reihe nach die "monitor-Eintrag" ist nicht das gleiche für die gleiche Zeilennummer.
Diese Oracle-Dokument beschreiben, dass ein Wert wie die folgenden:
BLOCKED
ich denke, das bedeutet, dass Sie aufgehört haben zu warten -- entweder benachrichtigt werden, oder timeout warten. Wenn Sie mein kleines test-Programm und stellen die timeouts können Sie sehen, die threads verschieben warten auf gesperrt.readLock = acquireReadLock(id);
auf der Linie 253. Ich aktualisiert meine Antwort mit den details, die Sperre. Die Art der Sperre, es ist versteckt durch eine Schnittstelle. Ich bin beeindruckt, dass gemeinsame sperren in der stack-trace so.wait
Linie. Siehe: grepcode.com/file/repo1.maven.org/maven2/org.apache.jackrabbit/...Wenn ein thread ein Objekt sperrt, aber wait()s ein anderer thread sperren kann das gleiche Objekt. Sie sollten in der Lage sein, um zu sehen, eine Anzahl von threads, "holding", die gleiche Sperre, die alle darauf warten.
AFAIK, die einzige andere Gelegenheit ist, wenn mehrere threads gesperrt und wartete und bereit sind, neu zu erwerben, der die Sperre z.B. auf einem notifyAll(). Sie warten nicht mehr, sondern können erst fortfahren, wenn Sie erhalten haben, die Sperre wieder. (nur ein thread zu einem Zeitpunkt kann die Zeit dies zu tun)
In unserem thread-dump, wir haben mehrere threads lock gleichen monitor, aber nur ein thread runnable. Ist es wahrscheinlich, weil der lock Wettbewerb, wir haben 284 andere threads warten auf die Schleuse. Mehrere threads die gleiche Sperre? sagte, dies existiert nur in der thread-dump für thread-dump ist keine Atomare operation.