Java Interthread Communication


Java provide benefit of avoiding thread pooling using interthread communication.

The wait(), notify(), notifyAll() of Object class. These method are implemented as final in Object.

All three method can be called only from within a synchronized context.

  • wait() tells calling thread to give up monitor and go to sleep until some other thread enters the same monitor and call notify.
  • notify() wakes up a thread that called wait() on same object.
  • notifyAll() wakes up all the thread that called wait() on same object.

Difference between wait() and sleep()

The important differences between wait and sleep methods.

wait()sleep()
called from synchronised blockno such requirement
monitor is releasedmonitor is not released
awake when notify() or notifyAll() method is called.not awake when notify() or notifyAll() method is called
not a static methodstatic method
wait() is generaly used on conditionsleep() method is simply used to put your thread on sleep.
//Inter thread communication to solver producer-consumer problem
public class NewMain {

    public static void main(String[] args) {
        //Common item object shared by both Producer and Consumer
        Item item = new Item();
        Producer producer = new Producer(item);
        Consumer consumer = new Consumer(item);
        producer.start();
        consumer.start();
    }
}

class Item {
    private int value;
    boolean valueSet = false;

    public synchronized void setItem(int i) throws InterruptedException {
        if (valueSet) {
            // Wait for consumer to consume an item
            wait();
        }

        value = i;
        System.out.print("Producer seting item: " + i);
        notify();
        valueSet = true;
    }

    public synchronized int getItem() throws InterruptedException {
        if (!valueSet) {
            // Wait for producer to produce an item
            wait();
        }

        System.out.println(" ->  Consumer geting item: " + value);
        notify();
        valueSet = false;
        return value;
    }
}

//Producer thread 
class Producer extends Thread {
    private Item item;
    int i;

    public Producer(Item item) {
        this.item = item;
    }

    public void run() {
        while (true) {
            try {
                //sleep() introduced to make producer slower then consumer
                sleep(1000);
                item.setItem(++i);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

//Consumer Thread
class Consumer extends Thread {
    private Item item;

    public Consumer(Item item) {
        this.item = item;
    }

    public void run() {
        while (true) {
            try {
                sleep(500);
                int temp = item.getItem();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
Output
Producer seting item: 1 ->  Consumer geting item: 1
Producer seting item: 2 ->  Consumer geting item: 2
Producer seting item: 3 ->  Consumer geting item: 3
Producer seting item: 4 ->  Consumer geting item: 4
Producer seting item: 5 ->  Consumer geting item: 5
.
.
.
Producer seting item: N ->  Consumer geting item: N

Share this article on