0

I'm trying to understand how notify & notifyAll are different.

Lets consider a case in which thread t1 is using a resource R. And now two threads t2 & t3 are waiting on the same resource. If t1 invokes notify method on R, which one of t2 & t3 will start? If t1 invokes notifyAll method on R, both t2 & t3 will be notified but as they are still competing for same resource only one of them should be able to start. And which one will be able to do so?

pkgajulapalli
  • 1,066
  • 3
  • 20
  • 44
  • From the [Java Docs](https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#notify--) *"Wakes up a single thread that is waiting on this object's monitor. If any threads are waiting on this object, one of them is chosen to be awakened. **The choice is arbitrary** and occurs at the discretion of the implementation. A thread waits on an object's monitor by calling one of the wait methods.*" – MadProgrammer Dec 14 '17 at 03:32
  • You can find your answer here - https://stackoverflow.com/questions/37026/java-notify-vs-notifyall-all-over-again – vinS Dec 14 '17 at 03:33

2 Answers2

0

You can't guess which one exactly will start to work. Java Docs says that it's the arbitrary choice.

0

Object.notify() will select a random waiting thread and notify that the lock is released and it can go ahead with obtaining the lock for itself. Object.notifyAll() will notify all the thread which are waiting for the lock of that object and they compete over to obtain the lock.

Initially we may think , then if i set varying priorities to each thread then i can control the sequence. But that not the case , priorities doesn't guarantee that the higher priority threads will run.

But if you really want to control the sequence of thread execution use thread synchronizers.

To test that priorities has little say in the Thread selection :

public class NotifyVSNotifyAll {


    public static void main(String[] args) {

        Object resource = new Object();

        Thread a=new Thread(()->{
                                   synchronized (resource) {
                                       System.out.println("A");
                                       try{
                                          Thread.sleep(2000);
                                          resource.notify();
                                      //resource.notifyAll();
                                       }catch(Exception E){}
                                   }  

                                 });
        Thread b=new Thread(()->{
            synchronized (resource) {
               System.out.println("B");
               }  

          });
        Thread c=new Thread(()->{
            synchronized (resource) {
               System.out.println("C");
               }  

          });

        a.setPriority(10);
        b.setPriority(1);
        c.setPriority(10);

        a.start();
        c.start();
        b.start();

    }


}

Hope its clear.
Roshan
  • 667
  • 1
  • 5
  • 15