Search code examples
javamultithreadinginter-process-communicat

why is notify not getting called in my java code


Here's my code:

public class ProducerConsumer
{

    public static void main(String[] args)
    {
        ProduceCosumeData p = new ProduceCosumeData();
        ProducerT pt= new ProducerT(p); // with p obj i am creating thread
        ConsumerT ct=new ConsumerT(p); // with same p obj i am creating thread
        pt.start();
        ct.start();  //i am starting 2 threads
    }
}

class ProduceCosumeData
{
    boolean flag;
    public synchronized void printStringP(int n)
    {
        for(int i=0;i<n;i++)
        {
            try{
                if(flag)   //for frist time flag is flase so, wait will skip
                    wait();
                else
                    flag=true;    //for next time onwards wait() will get call

                System.out.print("Pay");
                notify();//after this why my wait() not canceling in inprintStringC()
            }catch(Exception e)
            {
                System.out.print(e);
            }
        }
    }
    public synchronized void printStringC(int n)
    {
        for(int i=0;i<n;i++)
        {
            try{
                wait();   // why it is not out of this after notify()
                System.out.print("Tm");
                notify();
            }catch(Exception e)
            {
                System.out.print(e);
            }
        }
    }
}

class ProducerT extends Thread
{
    ProduceCosumeData p;
    ProducerT(ProduceCosumeData p)
    { 
        this.p=p;   // i am saving the same obj for both threads
    }   
    public void run()
    {
        p.printStringP(10); //it will print 10 times pay
    }
}

class ConsumerT extends Thread
{
    ProduceCosumeData p;
    ConsumerT(ProduceCosumeData p)
    { 
        this.p=p;   // i am saving the same obj for both threads
    }
    public void run()
    {
        p.printStringC(10);   //it will print 10 times tm
    }
}

I am expecting the following output:

PayTm
PayTm
PayTm
... 10 times

but what I'm getting output is this:

Pay..

This is followed by a long wait.

The above two functions are in same object.
Why is the notify not releasing the wait() function? Even when I use notifyAll(), the output remains the same.


Solution

  • In you code, one of your threads is calling notify and the other is still not waiting. This produces a deadlock with both threads waiting.

    You need to fix your use of the synchronization flag, don't call wait if it is not needed. Also, checking the locking condition is still available after the wait() is a good practice.

    This is your ProduceConsumeData class with the use of the flag fixed:

    class ProduceCosumeData
    {
        boolean flag;
        public synchronized void printStringP(int n)
        {
            for(int i=0;i<n;i++)
            {
                try{
                    while (flag == true) {   
                        wait();
                    }
                    flag=true;
                    System.out.print("Pay");
                    notify();
                }catch(Exception e)
                {
                    System.out.print(e);
                }
            }
        }
        public synchronized void printStringC(int n)
        {
            for(int i=0;i<n;i++)
            {
                try{
                    while(flag == false) {
                        wait();
                    }
                    System.out.print("Tm");
                    flag = false;
                    notify();
                }catch(Exception e)
                {
                    System.out.print(e);
                }
            }
        }
    }