2

I am still learning on Threads following java tutorials of oracle website.

With regarding to the wait() and notifyAll(), I have written some code. My expected output is print the message in run() 10 times and print the "Fun stopped by StopFun Thread" message in guardedJoy(GuardedBlock guardedBlock) method when the 'joy' set to false in the run method.

This is my code.

public class GuardedBlock {

private boolean joy = true;

public synchronized void guardedJoy(GuardedBlock guardedBlock) {

    System.out.println(Thread.currentThread().getName() + " Guard Joy method started");
    while (guardedBlock.joy) {
        try {
            System.out.println(Thread.currentThread().getName() + " Going to waiting state");
            guardedBlock.wait();
        } catch (InterruptedException ex) {
        }
    }
    System.out.println("Fun stopped by StopFun Thread");
}

private static class StopFun implements Runnable {

    private GuardedBlock guardedBlock;

    public StopFun(GuardedBlock guardedBlock) {
        this.guardedBlock = guardedBlock;
    }

    @Override
    public void run() {

        for (int x = 0; x < 100; x++) {
            try {
                Thread.sleep(500);
                System.out.println("Allowing fun since its only " + x + " times - " + Thread.currentThread().getName());

                if (x == 10) {
                    guardedBlock.joy = false;
                    guardedBlock.notifyAll();
                    break;
                }
            } catch (InterruptedException ex) {
            }
        }
    }
}

public static void main(String[] args) {

    GuardedBlock guardedBlock = new GuardedBlock();

    StopFun sf = new StopFun(guardedBlock);
    Thread stopFun = new Thread(sf);
    stopFun.start();

    guardedBlock.guardedJoy(guardedBlock);
    }
}

The code in the run method runs fine but afterwards it throws an exception like this.

Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
    at java.lang.Object.notifyAll(Native Method)
    at Synchronization.GuardedBlock$StopFun.run(GuardedBlock.java:38)
    at java.lang.Thread.run(Thread.java:748)

I went through couple of questions and answers in the site like this and this but could not figure out what exactly I am doing wrong. A help is much valued.

Thanks.

1
  • The documentation is your friend: “Throws: IllegalMonitorStateException - if the current thread is not the owner of this object's monitor.” Commented Nov 21, 2017 at 22:13

1 Answer 1

3

wait() and notify()/notifyAll() must be called in a synchronized block.

synchronized (guardedBlock) {
    guardedBlock.notifyAll();
}

and so on.

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for the answer. I have a question though.wait() is already in a synchronized method. So do I need to introduce a separate synchronized block?
Sorry, I did not see that the method is synchronized. But it is synchronized on this, and wait() is called on guardedBlock. In your program is so happens that guardedBlock matches this at the moment of the call due to guardedBlock.guardedJoy(guardedBlock);, and it should work without an additional synchronized block, but this is a bit fragile. And of course, notifyAll() must be under synchronization as well.
It's better to place guardedBlock.joy = false; in synchronized block as well.
Thanks both of you for the clarification :)
Did you ever figure this out because I'm using your code and placed the call to notifyAll() in a synchronized method and still receive the error...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.