Java Object notify() Method

The Object.notify() method in Java is used for thread communication, specifically in the context of multithreading and synchronization.

Table of Contents

  1. Introduction
  2. notify() Method Syntax
  3. Examples
    • Basic Notification
    • Using notify() with wait()
  4. Real-World Use Case
  5. Conclusion

Introduction

The Object.notify() method is a member of the Object class in Java. It is used to wake up a single thread that is waiting on the object's monitor. If multiple threads are waiting on this object's monitor, one of them is chosen to be awakened. The exact thread chosen is not specified and depends on the implementation of the JVM.

notify()() Method Syntax

The syntax for the notify() method is as follows:

public final void notify()

This method does not return any value and throws an IllegalMonitorStateException if the current thread is not the owner of the object's monitor.

Examples

Basic Notification

To use the notify() method, you need to have a thread that calls wait() on the object's monitor and another thread that calls notify() to wake it up.

Example

class NotifyExample {
    private final Object lock = new Object();

    public void waitingMethod() {
        synchronized (lock) {
            try {
                System.out.println("Waiting thread is going to wait...");
                lock.wait();
                System.out.println("Waiting thread is resumed.");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public void notifyingMethod() {
        synchronized (lock) {
            System.out.println("Notifying thread is going to notify...");
            lock.notify();
            System.out.println("Notifying thread has called notify.");
        }
    }

    public static void main(String[] args) {
        NotifyExample example = new NotifyExample();

        Thread waitingThread = new Thread(example::waitingMethod);
        Thread notifyingThread = new Thread(example::notifyingMethod);

        waitingThread.start();

        try {
            // Ensure the waiting thread starts waiting before the notifying thread calls notify
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        notifyingThread.start();
    }
}

Output:

Waiting thread is going to wait...
Notifying thread is going to notify...
Notifying thread has called notify.
Waiting thread is resumed.

Using notify() with wait()

The notify() method is typically used in conjunction with the wait() method to coordinate activities between threads.

Example

class SharedResource {
    private final Object lock = new Object();
    private boolean conditionMet = false;

    public void waitingMethod() {
        synchronized (lock) {
            while (!conditionMet) {
                try {
                    System.out.println("Waiting thread is going to wait...");
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("Condition met. Waiting thread is resumed.");
        }
    }

    public void notifyingMethod() {
        synchronized (lock) {
            conditionMet = true;
            System.out.println("Notifying thread is going to notify...");
            lock.notify();
            System.out.println("Notifying thread has called notify.");
        }
    }

    public static void main(String[] args) {
        SharedResource resource = new SharedResource();

        Thread waitingThread = new Thread(resource::waitingMethod);
        Thread notifyingThread = new Thread(resource::notifyingMethod);

        waitingThread.start();

        try {
            // Ensure the waiting thread starts waiting before the notifying thread calls notify
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        notifyingThread.start();
    }
}

Output:

Waiting thread is going to wait...
Notifying thread is going to notify...
Notifying thread has called notify.
Condition met. Waiting thread is resumed.

Real-World Use Case

Producer-Consumer Problem

In a real-world scenario, the notify() method can be used to solve the producer-consumer problem where producers put items into a shared resource and consumers take items out. The notify() method can be used to notify consumers when items are added and notify producers when space is available.

Example

import java.util.LinkedList;
import java.util.Queue;

class ProducerConsumerExample {
    private final Queue<Integer> queue = new LinkedList<>();
    private final int MAX_SIZE = 5;
    private final Object lock = new Object();

    public void produce() throws InterruptedException {
        int value = 0;
        while (true) {
            synchronized (lock) {
                while (queue.size() == MAX_SIZE) {
                    lock.wait();
                }
                queue.offer(value);
                System.out.println("Produced: " + value);
                value++;
                lock.notify();
            }
            Thread.sleep(1000); // Simulate time taken to produce an item
        }
    }

    public void consume() throws InterruptedException {
        while (true) {
            synchronized (lock) {
                while (queue.isEmpty()) {
                    lock.wait();
                }
                int value = queue.poll();
                System.out.println("Consumed: " + value);
                lock.notify();
            }
            Thread.sleep(1000); // Simulate time taken to consume an item
        }
    }

    public static void main(String[] args) {
        ProducerConsumerExample example = new ProducerConsumerExample();

        Thread producerThread = new Thread(() -> {
            try {
                example.produce();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        Thread consumerThread = new Thread(() -> {
            try {
                example.consume();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        producerThread.start();
        consumerThread.start();
    }
}

Output:

Produced: 0
Consumed: 0
Produced: 1
Consumed: 1
Produced: 2
Consumed: 2
...

Conclusion

The Object.notify() method in Java is a crucial tool for thread communication and synchronization. By understanding how to use this method, you can coordinate activities between multiple threads effectively. Whether you are using it for basic notification, coordinating with wait(), or implementing complex scenarios like the producer-consumer problem, the notify() method provides a powerful mechanism for managing thread interactions in Java applications.

Comments