All these methods belong to object class as final so that all classes have them. They must be used within a synchronized block only.
- wait()-It tells the calling thread to give up the lock and go to sleep until some other thread enters the same monitor and calls notify().
- notify()-It wakes up one single thread that called wait() on the same object. It should be noted that calling notify() does not actually give up a lock on a resource.
- notifyAll()-It wakes up all the threads that called wait() on the same object.
- Use of synchronized block to ensures that only one thread runs at a time.
package com.smartjavaguru;
//Java program to demonstrate inter-thread communication
//(wait(), join() and notify()) in Java
public class ThreadInterCommunication {
public static void main(String[] args) {
BikeFactory bike=new BikeFactory();
new Producer(bike);
new Consumer(bike);
}
}
class BikeFactory
{
private int bike;
// this boolean is used to control thread communication wait method
Boolean check=false;
// synchronized block ensures only one thread running at a time.
public synchronized void manufature(int bike) {
if(check) {
try {
// releases the lock on shared resource
wait();
// and waits till some other method invokes notify().
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(" Number of bikes
Manufactured and ready for sale::"+bike);
this.bike=bike;
// notifies the produce thread that it can wake up.
notify();
check=true;
}
// synchronized block ensures only one thread running at a time.
public synchronized void sale() {
if(!check) {
try {
// releases the lock on shared resource
wait();
// and waits till some other method invokes notify().
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(" Number of bikes are sold out ::"+bike);
// notifies the produce thread that it can wake up.
notify();
check=false;
}
}
class Producer implements Runnable
{
BikeFactory bikefactory;
public Producer(BikeFactory bikefactory) {
this.bikefactory = bikefactory;
// Create a thread object that calls producer()
Thread t=new Thread(this,"Producer");
t.start();
}
public void run() {
int i=0;
while(true) {
bikefactory.manufature(++i);
try {
new Thread().sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Consumer implements Runnable
{
BikeFactory bikeFactory;
public Consumer(BikeFactory bikeFactory) {
this.bikeFactory = bikeFactory;
// Create another thread object that calls consumer()
Thread t=new Thread(this,"Consumer");
t.start();
}
public void run() {
while(true) {
bikeFactory.sale();
try {
// this makes the produce thread to run first.
new Thread().sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
