java.lang.IllegalMonitorStateException: object not locked by thread before wait()
Asked Answered
P

1

6

But I am synchronizing on the 'roster' object everywhere it gets new'ed. How come ?

The offending code:

 public Roster getRoster() {
    if (roster == null) {
        return null;
    }

    if (!roster.rosterInitialized) {
        try {
            synchronized (roster) {
                roster.reload();
                long waitTime = SmackConfiguration.getPacketReplyTimeout();
                long start = System.currentTimeMillis();
                while (!roster.rosterInitialized) {
                    if (waitTime <= 0) {
                        break;
                    }
                    roster.wait(waitTime);
                    long now = System.currentTimeMillis();
                    waitTime -= now - start;
                    start = now;
                }
            }
        }
        catch (InterruptedException ie) {
            // Ignore.
        }
    }
    return roster;
}
Perkins answered 16/5, 2012 at 16:13 Comment(1)
where do you call notifyAerodonetics
L
8

With "gets new'ed" you mean you create a new roster object?

Are you sure you are synchronizing correctly? Synchronizsation happens on instances, not on variables. So if you do e.g.

synchronized(roster) {
  roster = new Roster();
  // do something
}

Then you only synchronized to the old, not the new roster.

So the following code should produce the same error:

Roster roster = new Roster();
Roster othervariable = roster;
synchronized(othervariable) {
  roster = new Roster(); // create a new roster
  othervariable.wait(1000); // OK, since synchronized with this instance!
  roster.wait(1000); // NOT OK, not synchronized with *new* roster!
}

Synchronizsation does not happen on the name of the variable, but on the contents. If you overwrite the contents, you do not re-synchronize to the new value!

Lucilucia answered 16/5, 2012 at 16:52 Comment(2)
whie you are right in this observation, I can't see how it could be the cause of the exception. Can you elaborate ?Perkins
Option #1 would be if roster.reload() could somehow change the object that the roster variable refers to. option #2 is that, before you get to the wait() call or while you're in it, some other thread changes what the roster variable refers to. In either case, the Roster that you synchronized on will not be the same Roster that you are wait()ing on.Certification

© 2022 - 2024 — McMap. All rights reserved.