Question

What happens when you call notifyAll method on an object that is not waiting? Should there be exception or is it normal situation?

Was it helpful?

Solution

It is completely normal. You can only notify all that waiting on one single monitor. Everybody else is not interested. The object on which you call notifyAll is just the monitor on which others are waiting. If nobody is waiting nobody has to be notified

OTHER TIPS

As you can see here, calling notifyAll() on an not waiting object does not have any effect.

alt text

The object is "waited on", not waiting itself. The thread is the one who is waiting. If no one is waiting, no one will wake up and nothing special will happen.

Perfectly normal situation.

Let's say you have a queue with a producer thread putting elements into it and a consumer threads removing elements from it.

Now the consumer might have emptied the queue and still be occupied with processing, so nobody is waiting for the queue to become non-empty. Now the producer adds a new element to the queue. He has to call notifyAll() to wake up the consumer if it were waiting. Adding additional logic to check if anyone is waiting and only calling notifyAll() in that case would add considerable (and very failur-prone) complexity to the scenario - it's much easier to just call notifyAll() every time.

Only waiting Objects get notified. Object.wait() blocks until a timeout or notify - so the question remains how or why would you think non waiting Objects would ever get notified ? it makes no sense.

I might be only splitting hairs ;-) It might not be strictly correct to think of threads being put from 'waiting' state to 'running' state on notifyAll; at least not without the caveat that the first thing a notified thread does is regrab the monitor lock. And since only one of the number of notified threads can grab it, the others will be blocked. BLOCKED (Thread.State.Blocked) is the thread state. But blocking is not the same as waiting because the blocked thread doesn't need another notify() signal to resume. [Well I know of spurious wake ups but maybe the opposite might also be true for some JVM implementations - a missed notify?]

public class HellBoy {
    public static class MyThread extends Thread {
        static final public Object sharedLock = new Object();

        public void run() {
            synchronized (sharedLock) {
                System.out.println("Gonna wait...");
                try {
                    sharedLock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Woken up but sleeping with the lock");
                try {
                    Thread.sleep(2500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("exiting and unlocking");
            }
        }
    }

    public static void main(String[] args) throws Exception {
        new MyThread().start();
        new MyThread().start();
        new MyThread().start();
        new MyThread().start();
        Thread.sleep(200);
        synchronized (MyThread.sharedLock) {
            MyThread.sharedLock.notifyAll();
        }
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top