-1

I am trying to use wait and notify to halt threads until a certain method is called. I currently have it setup as the following:

On thread has a method with:

    public void toggleTurnOver(){
    if(turnOver == false){
        turnOver = true;
        synchronized(this){
            for(Player p: playerList){
                p.notify();
            }
        }
    }else{
        turnOver = false;
    }
}

This method will be what is waking up the other wait that is located in this thread:

                        synchronized(myGame){
                        if(!myGame.getTurnOver()){
                            try {
                                wait();
                            } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                            pr.println(myGame.getTurnOver());
                            pr.flush();
                        }
                    }

They are synchronized on the same object so am not sure what would be causing that exception to be thrown. Any ideas?

Exact error thrown is:

Exception in thread "Thread-3" Exception in thread "Thread-2" java.lang.IllegalMonitorStateException
    at java.lang.Object.wait(Native Method)
    at java.lang.Object.wait(Object.java:503)
    at Player.run(Player.java:112)
java.lang.IllegalMonitorStateException
    at java.lang.Object.notify(Native Method)
    at Game.toggleTurnOver(Game.java:764)
    at Game.run(Game.java:386)
awmusic12635
  • 1,241
  • 2
  • 11
  • 13

2 Answers2

4

First sentence in the documentation:

Thrown to indicate that a thread has attempted to wait on an object's monitor or to notify other threads waiting on an object's monitor without owning the specified monitor.

You are notifying on p, so you have to synchronize on p:

for(Player p: playerList) {
  synchronized(p){
    p.notify();
  }
}

Same thing when waiting: you have to synchronize on the object you're waiting (assuming this code is in Player class):

if(!myGame.getTurnOver()){
    try {
        synchronized(this){
            wait();
        }
    } catch (InterruptedException e) {
        // ...
    }
}
king_nak
  • 11,313
  • 33
  • 58
  • Not only is that the first sentence in the docs, it's also the ONLY sentence excluding inherited constructors – Ordous May 13 '14 at 16:01
0

Quoting my favorite page in the internet:

Let thread t be the thread executing the wait method on object m, and let n be the number of lock actions by t on m that have not been matched by unlock actions. One of the following actions occurs:
- If n is zero (i.e., thread t does not already possess the lock for target m), then an IllegalMonitorStateException is thrown.
- blah blah blah

As this implies, you not only have to be synchronized on the same object when calling notify, it also has to be the same object that you are waiting and notifying on. In this case you are synchronizing on myGame, but are waiting and notifying on Player

Ordous
  • 3,844
  • 15
  • 25