Java notify() Method in Threads Synchronization with Examples


Introduction

The Object class contains a definition for the notify () method. Only one thread that is waiting for an item is wakes up by it and that thread then starts to run. A single thread can be awakened using the notify () method of the thread class. When using the notify () method while several threads are waiting for a notice, only one thread will actually get the notification and forces the others to continue waiting.

Let us discuss the Java notify () method in Threads Synchronization, along with its usage and programming examples. We will look into how it improves thread synchronization and inter-thread communication.

Explanation of notify () Method in Java

The “notify ()” method belongs to the Object class in Java and is used to facilitate inter-thread communication and coordination. When a thread invokes notify () on an object, it wakes up one of the waiting threads that called wait () on the same object. The awakened thread moves from the waiting state to the runnable state, and it will attempt to reacquire the object's monitor lock to continue its execution.

We must know that the notify () method does not handpick which thread to wake up. The choice of the awakened thread depends on the JVM's internal implementation and may vary between each Java runtime environment. If no threads are waiting on the object, the notify () method call has no effect.

Seller and Customer Problem by using notify () method

This particular program belongs to how to Seller and Customer Problems by using notify () method.

Example

import java.util.LinkedList;
import java.util.Queue;
public class CustomerItems 
{
   private final Object lock = new Object();
   private Queue<Integer> buffer = new LinkedList<>();
   private final int capacity = 10;
   public void produce() throws InterruptedException {
      synchronized (lock) {
         while (buffer.size() == capacity) 
         {
            lock.wait();
         }
         int items = 1; 
         buffer.add(items);
         System.out.println("Number of Sold items: " + items);
         lock.notify();
      }
   }
   public void consume() throws InterruptedException {
      synchronized (lock) {
         while (buffer.isEmpty()) {
            lock.wait();
         }
         int ValueofConsumeditem = buffer.poll();
         System.out.println("Number of Consumed items: " + ValueofConsumeditem);
         lock.notify();
      }
   }
   public static void main(String args []) 
   {
      CustomerItems example = new CustomerItems();

      Thread producerThread = new Thread(() -> {
         try {
            while (true) {
               example.produce();
               Thread.sleep(1000); 
            }
         } catch (InterruptedException e) {
            e.printStackTrace();
         }
      });
      Thread consumerThread = new Thread(() -> {
         try {
            while (true) {
               example.consume();
               Thread.sleep(1500); 
            }
         } catch (InterruptedException e) {
            e.printStackTrace();
         }
      });
      producerThread.start();
      consumerThread.start();
   }
}

Output

Number of Sold items: 1
Number of Consumed items: 1
Number of Sold items: 1
Number of Consumed items: 1
Number of Sold items: 1
Number of Consumed items: 1
Number of Sold items: 1
Number of Sold items: 1
Number of Consumed items: 1
Number of Sold items: 1
Number of Consumed items: 1
Number of Sold items: 1
Number of Sold items: 1
Number of Consumed items: 1
Number of Sold items: 1
Number of Consumed items: 1
Number of Sold items: 1

For this at first, we have imported some important packages in the program.

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

After that we have defined class named CustomerItems. Inside the class we have created an object of that particular class and made a linked list.

private final Object lock = new Object();
private Queue<Integer> buffer = new LinkedList<>();

Then we have declared a variable named capacity which is final and integer type and assigned some values to that particular integer. Then, we have called a function named produce () which there an interruptedExecution and do some synchronization work.

public void consume() throws InterruptedException

If the buffer is full user have to wait till the buffer is empty. If the buffer is empty, then user have the permission to enter some values to this buffer. Now we have simply printed the consumed value which is kept in the buffer by the user.

int ValueofConsumeditem = buffer.poll();
System.out.println("Number of Consumed items: " + ValueofConsumeditem)

Then we have called the main () function and inside this function we have created the object named example.

CustomerItems example = new CustomerItems ();

Now we have created a thread top do this particular work.

Thread producerThread = new Thread(() ->

And call the function example ().

example.produce();
Thread.sleep(1500);

Now we have started the producer thread and consumer thread respectively.

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

show the use of Java notify () Method

In this particular programming example, we will see another application of notify () method.

Example

public class BossThread 
{
   public static void main (String args [])
   {
      WorkerThread workerThread = new WorkerThread();
      workerThread.start();
      synchronized (workerThread) {
         try {
            // Display message only
            System.out.println("we now wait for the WorkerThread to finish!!!");
            // we wait() method for the main thread 
            workerThread.wait();
         }
         catch (InterruptedException e) {
            e.printStackTrace();
         }
         // Print result by the WorkerThread 
         System.out.println("Result is: " + workerThread.getResult());
      }
   }
}
class WorkerThread extends Thread 
{
   private int output;
   @Override
   public void run()
   {
      synchronized (this) 
      {
         for (int mp = 0; mp < 20; mp++) 
         {
            output += mp;
         }
         // use notify() to wake up the waiting thread
         notify();
      }
   }
   public int getResult() {
      return output;
   }
}

Output

we now wait for the WorkerThread to finish!!!
Result is: 190

In this program at first, we have defined a class named BossThread and inside the class we have called the main () function. Inside the main () function we have created a thread and started the thread.

WorkerThread workerThread = new WorkerThread();
workerThread.start();

Now we have done some synchronizing work and it is very important task to complete the task in a systematic way.

synchronized (workerThread) {
   try {
   // Display message only
   System.out.println("we now wait for the WorkerThread to finish!!!");

Finally, we have simply printed the result of workerthread.

System.out.println("Result is: " + workerThread.getResult());

After that we have defined another class named WorkerThread which extends the class thread.

class WorkerThread extends Thread	

Inside this class we have declared a variable named “output” which was final and integer type. Now we have executed the run () method and done some synchronizing work inside the run () function. Now we have use notify () to wake up the waiting thread and call another function named getResult () to get the desire output from the function.

public int getResult() {
   return output;
   }
}

Conclusion

In this particular article we learnt a lot about the configuration and the application of notify () method regarding the synchronization of thread. In the thread portion synchronization is the most crucial topic. To learn the synchronization tropic properly we have to know in detail about the notify () to cover up the entire thread topic.

Updated on: 04-Oct-2023

127 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements