Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is notifyAll() required at the end of a synchronized block?

Tags:

java

I used to write a synchronized block like:

synchronized(foobar) {
    // do something
}

But, recently I saw someone write:

synchronized(foobar) {
    // do something
    foobar.notifyAll();
}

Is foobar.notifyAll(); necessary? What happens if I omit it?

like image 772
Wenhao Ji Avatar asked Feb 12 '13 15:02

Wenhao Ji


4 Answers

You don't need to do this. You only have to do it if the object (here foobar) is waiting to be notified. Notify only Wakes up all threads that are waiting on this object's monitor.

like image 43
poitroae Avatar answered Oct 10 '22 17:10

poitroae


The short answer is that is depends on what you are doing.

If the goal of the synchronized block is simply to ensure that access / updates to a data structure are performed safely, then notify() or notifyAll() serves no purpose.

On the other hand, if the goal is to implement a "condition variable" then the notify() or notifyAll() calls work with a wait call like this ... for example:

private boolean flag;
private final Object mutex = new Object();

public void awaitFlag(boolean flag) {
    synchronized (mutex) {
        while (this.flag != flag) {
            mutex.wait();
        }
    }
}

public void setFlag(boolean flag) {
    synchronized (mutex) {
        this.flag = flag;
        mutex.notifyAll();
    }
}

The above implements a simple mechanism where threads call awaitFlag() to wait for the flag to become true or false. When another thread calls setFlag() to change the flag, all of the threads that are currently waiting for the flag to change will get woken up by the notifyAll(). This is an example where the notifyAll() is essential to the working of the code.


So to understand whether the notify or notifyAll code is necessary, you need to figure out if some other code might call wait on the same mutex / lock object.

like image 142
Stephen C Avatar answered Oct 10 '22 17:10

Stephen C


In Java, you can use wait(), notify() and notifyAll() to achieve thread co-ordination. See How to use wait and notify in Java?

like image 42
Dilum Ranatunga Avatar answered Oct 10 '22 17:10

Dilum Ranatunga


The notifyAll() is to tell any other thread sleeping in a foobar.wait() that the current thread is about to release the lock and they can compete for the resource again.

like image 30
Gazzonyx Avatar answered Oct 10 '22 18:10

Gazzonyx