Search code examples
javamultithreadingsynchronizationwaitjava-threads

How to make notify() execute before wait(), i tried using sleep() but still not working


I have the following Thread example:

class Q
{
    int num;
    public synchronized void put(int num) {
        System.out.println("Put :"+num);
        this.num = num;
        try {Thread.sleep(100);} catch (Exception e) {}
        notify();
        try {wait();} catch (Exception e) {}
    }
    public synchronized void get() {
        try {wait();} catch (Exception e) {}
        System.out.println("Get :"+num);
        notify();
    }
}
class Producer implements Runnable
{
    Q q;
    public Producer(Q q) {
        this.q = q;
        Thread t = new Thread(this,"Producer");
        t.start();
    }
     public void run() {
         int i = 0;
         while(true) {
             q.put(i++);
                try {Thread.sleep(1000);} catch (Exception e) {}
         }  
     }
}
class Consumer implements Runnable
{
    Q q;
    Thread t;
    public Consumer(Q q) {
        this.q = q;
        t = new Thread(this,"Consumer");
        t.start();
    }
     public void run() {
         while(true) {
             q.get();
            try {Thread.sleep(500);} catch (Exception e) {}
         }     
     }
}
public class InterThread {
    public static void main(String[] args) {
        Q q = new Q();
        new Producer(q);
        new Consumer(q);
    }
}

I'm trying to run two threads, consumer and producer, in a loop. sharing the same object q, one thread incrementing q.num and printing the value of it, and the other is consuming q.num by just printing its value. The result I'm getting in a console is "Put :0" and stops there, consumer thread not being called, even though I used Thread.sleep(100); before calling notify() in the producer thread, why !!?


Solution

  • In this case, Producer thread is starting before Consumer. notify() is getting called, following by that wait() getting called. Producer thread goes in waiting state, releases acquired lock.

    // producer
    notify();
    try {
       System.out.println(Thread.currentThread().getName() + " Put :"+num);
       this.wait(); // lock released
    } 
    catch (Exception e) {
    
    }
    

    Now consumer thread acquires the lock, wait() is executed. Consumer goes in the waiting state.

    // consumer
    try {
       System.out.println(Thread.currentThread().getName() + "Get :"+num);
       this.wait(); // Both the threads are waiting
    } 
    catch (Exception e) { 
    
    }
    

    Now both the threads are waiting for notify call from the other thread Note that Sleep() method doesn't release the lock , so there is no point in calling calling Thread.sleep before the producer's notify

    difference-between-wait-and-sleep