Difference Between notify() and notifyAll() in Java

Last Updated : 17 Mar, 2026

In Java, notify() and notifyAll() are used in inter-thread communication to wake up threads waiting on an object’s monitor. Both are part of the Object class but differ in how many threads they wake. The notify() and notifyAll() methods with wait() methods are used for communication between the threads.

  • notify() wakes up only one waiting thread, while notifyAll() wakes all waiting threads
  • notify() is more efficient but may cause thread starvation, whereas notifyAll() avoids starvation

notify() Method

The notify() method in Java is used for inter-thread communication to wake up a thread that is waiting on an object’s monitor. It is defined in the Object class and works with wait() inside synchronized blocks.

  • Wakes up one randomly selected waiting thread
  • Does not release the lock immediately after calling
  • Must be used inside a synchronized method or block
Java
class Geek1 extends Thread {
    public void run()
    {
        synchronized (this)
        {
            System.out.println(
                Thread.currentThread().getName()
                + "...starts");
            try {
                this.wait();
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(
                Thread.currentThread().getName()
                + "...notified");
        }
    }
}
class Geek2 extends Thread {
    Geek1 geeks1;
  
    Geek2(Geek1 geeks1){ 
      this.geeks1 = geeks1; 
    }
  
    public void run()
    {
        synchronized (this.geeks1)
        {
            System.out.println(
                Thread.currentThread().getName()
                + "...starts");

            try {
                this.geeks1.wait();
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(
                Thread.currentThread().getName()
                + "...notified");
        }
    }
}
class Geek3 extends Thread {
    Geek1 geeks1;
    Geek3(Geek1 geeks1) { this.geeks1 = geeks1; }
    public void run()
    {
        synchronized (this.geeks1)
        {
            System.out.println(
                Thread.currentThread().getName()
                + "...starts");
            this.geeks1.notify();
            System.out.println(
                Thread.currentThread().getName()
                + "...notified");
        }
    }
}
class MainClass {
    public static void main(String[] args)
        throws InterruptedException
    {

        Geek1 geeks1 = new Geek1();
        Geek2 geeks2 = new Geek2(geeks1);
        Geek3 geeks3 = new Geek3(geeks1);
        Thread t1 = new Thread(geeks1, "Thread-1");
        Thread t2 = new Thread(geeks2, "Thread-2");
        Thread t3 = new Thread(geeks3, "Thread-3");
        t1.start();
        t2.start();
        Thread.sleep(100);
        t3.start();
    }
}

Output: 

Thread-1...start
Thread-2...starts
Thread-3...starts
Thread-3...notified
Thread-1...notified

notifyAll() Method

The notifyAll() method in Java is used for inter-thread communication to wake up all threads waiting on an object’s monitor. It is defined in the Object class and is typically used when multiple threads need to resume execution.

  • Wakes up all waiting threads on the same object
  • Threads compete to re-acquire the lock before continuing
  • Must be called inside a synchronized method or block
Java
class Geek1 extends Thread {
    public void run()
    {
        synchronized (this)
        {
            System.out.println(
                Thread.currentThread().getName()
                + "...starts");
            try {
                this.wait();
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(
                Thread.currentThread().getName()
                + "...notified");
        }
    }
}
class Geek2 extends Thread {
    Geek1 geeks1;
  
    Geek2(Geek1 geeks1){ 
      this.geeks1 = geeks1; 
    }
  
    public void run()
    {
        synchronized (this.geeks1)
        {
            System.out.println(
                Thread.currentThread().getName()
                + "...starts");

            try {
                this.geeks1.wait();
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(
                Thread.currentThread().getName()
                + "...notified");
        }
    }
}
class Geek3 extends Thread {
    Geek1 geeks1;
    Geek3(Geek1 geeks1) { this.geeks1 = geeks1; }
    public void run()
    {
        synchronized (this.geeks1)
        {
            System.out.println(
                Thread.currentThread().getName()
                + "...starts");

            this.geeks1.notifyAll();
            System.out.println(
                Thread.currentThread().getName()
                + "...notified");
        }
    }
}
class MainClass {
    public static void main(String[] args)
        throws InterruptedException
    {

        Geek1 geeks1 = new Geek1();
        Geek2 geeks2 = new Geek2(geeks1);
        Geek3 geeks3 = new Geek3(geeks1);
        Thread t1 = new Thread(geeks1, "Thread-1");
        Thread t2 = new Thread(geeks2, "Thread-2");
        Thread t3 = new Thread(geeks3, "Thread-3");
        t1.start();
        t2.start();
        Thread.sleep(100);
        t3.start();
    }
}

Output
Thread-1...starts
Thread-2...starts
Thread-3...starts
Thread-3...notified
Thread-1...notified
Thread-2...notified

notify() Vs notifyAll() Method

Featurenotify()notifyAll()
Threads WokenWakes one waiting threadWakes all waiting threads
SelectionThread is randomly selectedAll threads are notified
PerformanceMore efficientLess efficient (more overhead)
RiskMay cause thread starvationAvoids starvation
ExecutionOnly one thread proceedsMultiple threads compete for lock
Use CaseWhen only one thread needs to runWhen all waiting threads should run
Comment