0

I am trying to implement standard Producer Consumer problem using java.

I done some code to do it.

Here is the code:

Producer Class:

class Producer implements Runnable
{

public Producer()
{
    new Thread(this,"Producer").start();
}

public synchronized void put()
{
    while(Q.valueset)
    {
        try
        {
            wait();
        }
        catch(Exception e)
        {
            System.out.println(e);
        }
    }
    Q.valueset=true;
    Q.i++;
    System.out.println("Put:"+Q.i);
    notify();
}
public void run()
{
    while(true)
    {
        put();
    }
}
}

Consumer class:

class Consumer implements Runnable
{
public Consumer()
{
    new Thread(this,"Consumer").start();
}

public synchronized void get()
{
    while(!Q.valueset)
    {
        try
        {
            wait();
        }
        catch(Exception e)
        {
            System.out.println(e);
        }
    }
    Q.valueset=false;
    notify();
    System.out.println("Get:"+Q.i);
}

public void run()
{
    while(true)
    {
        get();
    }

}
}

Another class for Static variables:

class Q
{
static boolean valueset=false;
static int i;
}

I am having one more class which only contains main and creates the instance of Producer And Consumer.

Now when i am trying to run this program it gives following output:

Put:1
put:2
Got:1
Got:2

I am having misconception related to Wait() and notify() that how it works and how object enters and out's from the monitor.i wanted to clear that concept.

Here the problem is also arising due to Wait and notify().

I know this is very basic question related to Multithreading but these these will help me to clear my misconception.

And i also wanted to understand what is the problem in my code.

I already gone through the following link:

producer - consumer multithreading in Java

Community
  • 1
  • 1
Nirav Kamani
  • 3,192
  • 7
  • 39
  • 68

2 Answers2

2

You need to wait() and notify() on some shared object. What you are doing now by using synchronized is waiting on the respective objects themselves, i.e. the Producer is waiting on the Producer and the Consumer on the Consumer object. You need to wait on something in Q.

From the Javadoc:

notify(): Wakes up a single thread that is waiting on this object's monitor.

wait(): The current thread must own this object's monitor. The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method or the notifyAll method. The thread then waits until it can re-obtain ownership of the monitor and resumes execution.

This object's monitor in your case is this, which is your Producer in the put() case and the Consumer in the get() case. But in order for the notify to notify the other Thread, they need to have the same monitor, i.e. they need to wait() on the same object. This object can be e.g. a Object variable in your Q.

To get you started, this is what I mean:

class Q
{
static boolean valueset=false;
static int i;
static Object myLock = new Object();
}

public void put() {
    synchronized (Q.myLock) { 
        while (Q.valueset) {
            try {
                Q.myLock.wait();
            } catch (Exception e) {
                System.out.println(e);
            }
        }
        Q.i++; //you forgot this as well
        System.out.println("Put:" + Q.i);
        Q.valueset = true;
        Q.myLock.notify();
    }
}

You can fill in the Consumer class yourself...

Put:1
Get:1
Put:2
Get:2
Put:3
Get:3
Put:4
Get:4
Community
  • 1
  • 1
jmiserez
  • 2,991
  • 1
  • 23
  • 34
  • ya that is what i mean to say why we needed shared object? and what lock does? – Nirav Kamani Nov 19 '13 at 07:24
  • Sorry I didn't understand you. What do you mean? – jmiserez Nov 19 '13 at 07:31
  • But yes you need to add a shared object to use as a monitor to the class Q: `static Object lock = new Object();` – jmiserez Nov 19 '13 at 07:33
  • It does not need to be named `lock`, you could also name it `abcdefg`: `static Object abcdefg = new Object();` – jmiserez Nov 19 '13 at 07:34
  • i am unable to understand "But yes you need to add a shared object to use as a monitor to the class Q: static Object lock = new Object();" what you are trying to say i am confused specially about the lock line. – Nirav Kamani Nov 19 '13 at 07:35
  • Every Java object has the methods `wait()` and `notify()`. Every single one of them. So you you can use any object that both threads can access for synchronization. But in your example, you don't have any shared objects, so we need to add one. I have updated the answer, the object is called `myLock` and it is an object of type `Object`. I have tested this answer and it works 100%, but you need to change the `Consumer` class in the same way. – jmiserez Nov 19 '13 at 07:39
  • ok finally what i found is to use wait and notify we need some shared object to which we can call wait and notify in my case individual both the producer and consumer one time puts and gets the item and finally DEADLOCKED because i am not having shred object and each therad is waiting for another am i right? – Nirav Kamani Nov 19 '13 at 07:41
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/41459/discussion-between-jmiserez-and-nirav-kamani) – jmiserez Nov 19 '13 at 07:41
0

This post explains the relationship between notify, wait, and other things you are looking for.

Difference between wait() and sleep()

Community
  • 1
  • 1
Corjava
  • 340
  • 2
  • 6
  • 17
  • Thanks for your support. I done reading of these link but i want to clearly understand how can i use these methods perfectly in my program. – Nirav Kamani Nov 19 '13 at 05:54