Ich habe einen Jstack Dump, der scheinbar sagt, dass mehrere Threads eine Sperre für das gleiche Objekt erworben haben. Wie ich es verstehe, ist das unmöglich, aber ist es das?Können mehrere Threads auf dasselbe Objekt warten?
Hier ist der Code mit dem entscheidenden Warte Anruf innerhalb Try-Block:
protected boolean waitMaxWaitingTime(UserInfo aUserInfo) throws EventServiceException {
final int theMaxWaitingTime = myConfiguration.getMaxWaitingTime();
if(theMaxWaitingTime <= 0) {
return true;
}
if(aUserInfo.isEventsEmpty()) {
//monitor for event notification and double checked
synchronized(aUserInfo) {
if(aUserInfo.isEventsEmpty()) {
try {
final long theStartTime = System.currentTimeMillis();
// --- THE CRUCIAL WAIT CALL ---
aUserInfo.wait(theMaxWaitingTime);
return (System.currentTimeMillis() - theStartTime >= theMaxWaitingTime);
} catch(InterruptedException e) {
throw new EventServiceException("Error on waiting max. waiting time!", e);
}
}
}
}
return false;
}
Und hier ist der jstack dump (selektiv):
"thread-79" #161 daemon prio=5 os_prio=0 tid=0x000000005d63c000 nid=0x322c in Object.wait() [0x000000007e93c000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at de.novanic.eventservice.service.connection.strategy.connector.ConnectionStrategyServerConnectorAdapter.waitMaxWaitingTime(ConnectionStrategyServerConnectorAdapter.java:92)
- locked <0x000000008b8de758> (a de.novanic.eventservice.service.registry.user.UserInfo)
"thread-77" #159 daemon prio=5 os_prio=0 tid=0x000000005d63a800 nid=0x5384 in Object.wait() [0x000000007e83c000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at de.novanic.eventservice.service.connection.strategy.connector.ConnectionStrategyServerConnectorAdapter.waitMaxWaitingTime(ConnectionStrategyServerConnectorAdapter.java:92)
- locked <0x000000008b8de758> (a de.novanic.eventservice.service.registry.user.UserInfo)
"thread-74" #156 daemon prio=5 os_prio=0 tid=0x000000006efe6000 nid=0x4828 in Object.wait() [0x000000007e25c000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at de.novanic.eventservice.service.connection.strategy.connector.ConnectionStrategyServerConnectorAdapter.waitMaxWaitingTime(ConnectionStrategyServerConnectorAdapter.java:92)
- locked <0x000000008b8de758> (a de.novanic.eventservice.service.registry.user.UserInfo)
Wie Sie mehrere verschiedene Themen sehen (gehen durch Namen und tid Thread-IDs, in diesem Thread thread-79
und thread-74
) haben offenbar eine Sperre für das gleiche UserInfo-Objekt (0x000000008b8de758) erworben und darauf gewartet. Habe ich mich geirrt oder haben mehrere Threads wirklich Lock erworben und warten auf ein einzelnes Objekt?
Das 'if' sollte ein' while' sein. – EJP
Außer wenn 'aUserInfo.isEventsEmpty()' ["happes-before"] hat (https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4.5) Einschränkungen. Sie dürfen DCL nicht verwenden. JVM ist frei, Anweisungen neu zu ordnen, solange Bedingungen erfüllt sind, bevor "passiert". Mit anderen Worten, Ihre Bedingung kann wahr sein, ohne dass alle angenommenen Operationen verarbeitet werden. Beispiel: Sie setzen einen booleschen Wert auf true, nachdem Sie ein Attribut festgelegt haben.JVM kann Boolean vor dem Setzen des Attributs setzen und kann sogar ein Attribut zuweisen, boolean auf true setzen und schließlich die Instanzinitialisierung (Konstruktoraufruf) verarbeiten. – LoganMzz
@EJP Und 'return' muss nach der Schleife durchgeführt werden;) – LoganMzz