Posts Java Multithreading - Wait and Notify
Post
Cancel

Java Multithreading - Wait and Notify

This following post is based on the Udemy Course: Java Multithreading


wait()

The wait() method is a part of java.lang.Object class. When wait() method is called, the calling thread stops its execution until notify() or notifyAll() method is invoked by some other Thread. The wait() method has 3 variations:

  • wait(): This is a basic version of the wait() method which does not take any argument. It will cause the thread to wait till notify is called.
  • wait(long timeout): This version of the wait() method takes a single timeout argument. It will cause the thread to wait either till notify is called or till timeout (One which occurs earlier).
  • wait(long timeout, int nanoseconds): This version of the wait() method takes a timeout argument as well as a nanosecond argument for extra precision.

notify()

The notify() method is defined in the Object class, which is Java’s top-level class. It’s used to wake up only one thread that’s waiting for an object, and that thread then begins execution. The thread class notify() method is used to wake up a single thread.

Oracle Doc

App.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package com.threads;

public class App {
 
 public static void main(String[] args){
   
  Processor processor = new Processor();
  
  //producer thread
  Thread t1 = new Thread(new Runnable() {
   
   @Override
   public void run() {
    try {
     processor.produce();
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
   }
  });
  
  //consumer thread
  Thread t2 = new Thread(new Runnable() {
   
   @Override
   public void run() {
    try {
     processor.consume();
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
   }
  });
  
  t1.start();
  t2.start();
  
  try {
   t1.join();
   t2.join();
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  
 }

}

Processor.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package com.threads;

import java.util.Scanner;

public class Processor {

 public void produce() throws InterruptedException {
  
  //producer thread will get the lock and run this method
  synchronized (this) {
   System.out.println("Producer running.");
   
   //causes the current thread to wait until it is awakened, typically by being notified or interrupted. 
   //this of it as relinquishing the intrinsic lock and waiting for a notification to get the lock again
   wait();
   
   //continue, once it gets the lock again
   System.out.println("Resumed");
  }
  
 }
 
 public void consume() throws InterruptedException {
  
  //we have added a sleep to ensure that producer thread gets the intrinsic lock on the current object first
  Thread.sleep(2000);
  
  Scanner scanner = new Scanner(System.in);
  
  //the consumer thread will get the lock once the producer thread calls "wait"
  synchronized (this) {
   
   //wait for return key in the input
   System.out.println("waiting for return");
   scanner.nextLine();
   
   //Wakes up a single thread that is waiting on this object'smonitor. 
   //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. 
   //The awakened thread will not be able to proceed until the current thread relinquishes the lock on this object. 
   //The awakened thread will compete in the usual manner with any other threads that might be actively competing to synchronize on this object; 
   //for example, the awakened thread enjoys no reliable privilege or disadvantage in being the next thread to lock this object. 
   notify();
   
   //even after calling notify, the producer thread can get the intrinsic lock only after this thread completes
   System.out.println("sleeping for 5 seconds");
   Thread.sleep(5000);
  }
  
 }
 
}
This post is licensed under CC BY 4.0 by the author.