4) Multithreading Lesson

Threads: wait() and notify()

4 min to complete · By Ryan Desmond

The wait() and notify() methods in Java are part of the Object class and are used for inter-thread communication, allowing threads to synchronize and cooperate. These methods are typically used in conjunction with the synchronized keyword.

Using wait() and notify() for Inter-Thread Communication

Consider a simple producer-consumer scenario where one thread (producer) produces an item, and another thread (consumer) consumes the item.

public class SharedResource {
  private int item;
  private boolean hasItem = false;

  public synchronized void produce(int newItem) {
    while (hasItem) {
      try {
        // Producer waits if the item is already present
        wait(); 
      } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
      }
    }
    item = newItem;
    hasItem = true;
    System.out.println("Produced: " + item);
    // Notify the consumer that a new item is available
    notify(); 
  }

  public synchronized void consume() {
    while (!hasItem) {
      try {
        // Consumer waits if there is no item
        wait(); 
      } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
      }
    }
    System.out.println("Consumed: " + item);
    hasItem = false;
    // Notify the producer that the item has been consumed
    notify(); 
  }
}

And consider this example usage:

public class Main {
  public static void main(String[] args) {
    SharedResource sharedResource 
      = new SharedResource();

    // Producer thread
    new Thread(() -> {
      for (int i = 1; i <= 5; i++) {
        sharedResource.produce(i);
      }
    }).start();

    // Consumer thread
    new Thread(() -> {
      for (int i = 1; i <= 5; i++) {
        sharedResource.consume();
      }
    }).start();
  }
}

In this example:

  • The produce method produces an item, sets hasItem to true, prints the produced item, and notifies the waiting consumer.
  • The consume method consumes an item, sets hasItem to false, prints the consumed item, and notifies the waiting producer.
  • The wait() method is used to make a thread wait until another thread invokes the notify() or notifyAll() method.
  • The notify() method wakes up one of the threads that are currently waiting.

Points to Note

  • Always use wait() inside a loop to handle spurious wake-ups.
  • wait() and notify() must be called from a synchronized context (within a synchronized method or block).

Summary: wait() and notify()

  • wait() and notify() facilitate inter-thread communication and synchronization.
  • wait() is used to make a thread wait until notified.
  • notify() is used to wake up a waiting thread.
  • Always use wait() inside a loop to handle spurious wake-ups.
  • wait() and notify() must be called from a synchronized context.