5

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?

Duncan Jones
  • 67,400
  • 29
  • 193
  • 254
Wenhao Ji
  • 5,121
  • 7
  • 29
  • 40
  • 1
    It is there to prevent deadlocks – DotNetRussell Feb 12 '13 at 15:59
  • AMR, the `synchronized` is there to prevent deadlocks, the `notifyAll()` is used to signal any other threads waiting on the monitor. – Dilum Ranatunga Feb 12 '13 at 16:00
  • But isn't a dead lock when all threads are waiting and there is no notification? – DotNetRussell Feb 12 '13 at 16:01
  • It is as necessary as tying your shoelaces. If you wanna go running, you better do, but not really for a casual walk. In other words, it's unnecessary unless it's necessary, and it's necessary when you want to make everyone wait for something to happen and then tell them they can do it because it happened. – Shark Feb 12 '13 at 16:03
  • `notify()` and `notifyAll()` are useful only when you called `wait()` somewhere. – shuangwhywhy Feb 12 '13 at 16:51

4 Answers4

5

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.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
4

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.

poitroae
  • 21,129
  • 10
  • 63
  • 81
2

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

Community
  • 1
  • 1
Dilum Ranatunga
  • 13,254
  • 3
  • 41
  • 52
1

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.

Gazzonyx
  • 213
  • 2
  • 7