简体   繁体   中英

JAVA consumer-producer multi-threaded application - flow of code

I was practicing this famous application and have a question. I found there are 4000 Q/A on this topic in this site, but none of them is related to this point and hence asking this question.

Here is the simple code -

class Resource {
    int contents;
    boolean available = false;
}

class Producer implements Runnable {
    Thread t;
    private Resource resource;

    public Producer(Resource c) {
        resource = c;
        t=new Thread(this);
        t.start();
    }

    public void run() {
        for (int i = 0; i < 3; i++) {
            synchronized (resource) {
                while (resource.available == true) {
                    //System.out.println("Producer -> calling wait");
                    try {
LINE 1                  resource.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } 
                }
LINE 2          resource.contents = i;
                resource.available = true;
                //System.out.println("Producer -> calling notify");
                resource.notify();
                System.out.println("Producer " + " put: " + resource.contents);
                try {
                    Thread.sleep((int)(Math.random() * 100));
                } catch (InterruptedException e) { }
            }
        }
    }
}

class Consumer implements Runnable {
    Thread t;
    private Resource resource;

    public Consumer(Resource c) {
        resource= c;
        t=new Thread(this);
        t.start();
    }

    public void run() {
        for (int i = 0; i < 3; i++) {
            synchronized (resource) {
                while (resource.available == false) {
                    System.out.println("Consumer -> calling wait");
                    try {
LINE 3                  resource.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
LINE 4          resource.available = false;
                //System.out.println("Consumer -> calling notify");
                resource.notify();
                System.out.println("Consumer " + " got: " + resource.contents);
            }
        }
    }
}

public class ProducerConsumerTest {
    public static void main(String[] args) {
        Resource c = new Resource ();
        Producer p1 = new Producer(c);
        Consumer c1 = new Consumer(c);
    }
}

And here is the output -

#1 Producer  put: 0
#2 Consumer  got: 0
#3 Consumer -> calling wait
#4 Producer  put: 1
#5 Consumer  got: 1
#6 Consumer -> calling wait
#7 Producer  put: 2
#8 Consumer  got: 2

So here is the flow of code -

#1 Since available=false, Producer will go to LINE 2, make available=true and notify the other thread.
#2 Since available=true, Consumer will go to LINE 4, make available=false and notify the other thread.
#3 So now code should go back to the Producer thread. But why Consumer is entering it's own wait() block at LINE 3?

Am I missing something simple? Can you please explain?

Many many thanks in advance.

You asked

3 So now code should go back to the Producer thread. But why Consumer is entering it's own wait() block at LINE 3?

well consumer thread will continue to run after it makes available=false and notify the other thread. Till producer thread does not make available=true it will call wait and blocked.

Best way to implement the producer/consumer pattern is through BlockingQueue

Here is the example

I don't see how your threads are coordinating their activity. When the Producer is sleeping it isn't waiting for resource. When the Consumer calls resource.notify() it is possible that no Producer is waiting for the resource.

As @ M Sach has already pointed out, the Consumer thread is free to continue processing.

At this point the two threads are not coordinating with each other via resource, so the observed behaviour seems to be as expected from a running Consumer and a sleeping Producer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM