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

android, java, locks, synchronize

Solution

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!

Problem

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; } ```

Original source