Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible for several threads to wait on same object?

I have a jstack dump that seemingly says that several threads have acquired a lock on the same object. As I understand this is suppose to be impossible but is it?

Here's the code with the crucial wait call inside 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;
}

And here's the jstack dump (selectively):

"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)

As you can see, several different threads (going by names and tid thread IDs, in this thread thread-79 and thread-74) have apparently acquired a lock on the same UserInfo object (0x000000008b8de758) and called wait on it. Am I mistaken or have several threads really acquired lock and called wait on a single object?

like image 433
denarced Avatar asked Oct 13 '15 09:10

denarced


2 Answers

Your dump shows that several threads are waiting on the object monitor (waiting to acquire it), and not that several threads (more than one) have acquired it (at the same time). The former is quite possible and normal. The latter cannot happen.

In other words, yes, several threads have acquired the lock/monitor but that happened serially (one after the other). Once a thread calls wait, it releases the lock and then another thread can acquire it (and then release it again, and so on).

like image 70
peter.petrov Avatar answered Sep 28 '22 14:09

peter.petrov


As you can see, several different threads (going by names and tid thread IDs) have apparently acquired a lock on the same UserInfo object (0x000000008b8de758) and called wait() on it.

This is absolutely right. Several threads have called wait() on the same object. This sounds counterintuitive at first, because the code is within a synchronized block.

The documentation explains this "mystery": the call of wait() releases the ownership of the monitor, letting other threads enter and start the wait if they wish to

The current thread must own this object's monitor. The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method or the notifyAll method. The thread then waits until it can re-obtain ownership of the monitor and resumes execution. (emphasis added)

like image 26
Sergey Kalinichenko Avatar answered Sep 28 '22 14:09

Sergey Kalinichenko