christ-yang
christ-yang

Reputation: 31

confused in a simple Producer-Consumer implement with synchronized, wait, notifyAll

in my code, I tried two similar condition codes in while loop to check the boxes is full when the producer thread needs to wait in producer code. but it's output is different, I am confused.

the error is when I use a variable named 'size' to save the value of boxes's size in thread's run code. in some cases, the program will be blocking like death.

Producer code:

public class Producer implements Runnable{
    private final List<String> boxes;
    private final int MAX_SIZE = 5;
    public Producer(List<String> aboxes) {
        super();
        this.boxes = aboxes;
    }
    @Override
    public void run() {
        while (true) {
            synchronized (boxes) {
                try {
                    int size = boxes.size(); // OR int size = this.boxes.size();

                    // while(MAX_SIZE == this.boxes.size()) {      OK
                    // while(MAX_SIZE == boxes.size()) {           OK
                    while (MAX_SIZE == size) {                  // ERROR
                        boxes.wait();
                    }

                    Thread.sleep(500);
                    String product = "product :  " + UUID.randomUUID().toString();
                    boxes.add(product);

                    boxes.notifyAll();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }  
        }
    }
}

Upvotes: 3

Views: 44

Answers (1)

Ashishkumar Singh
Ashishkumar Singh

Reputation: 3600

The condition in while statement in your current case is static i.e. for MAX_SIZE == size value of both variable doesn't change when the while loop is evaluated again.

When notify is called on boxes and the producer thread is notified, the while loop is evaluated again. As both value have not changed, both will have value of 5 and when the loop is evaluated, it value will again be 5. So while condition will be 5==5 resulting in wait being called again. i.e. Once it entered the while loop, the condition will always be true, resulting in the infinite blocking.

But with condition MAX_SIZE == boxes.size(), the value of boxes.size() is dynamic and it will be changed, I guess by consumer here. Let's say, consumer remove one element from this list so boxes.size()=4 and it calls notify on boxes. So the producer thread is notified and the condition in producer becomes 5 == 4 which results in while condition being false and exit the loop. Hence the code execute as expected

Upvotes: 4

Related Questions