путать в простой реализации Producer-Consumer с синхронизированными, ждать, уведомить все - PullRequest
3 голосов
/ 14 апреля 2019

в моем коде я попробовал два похожих кода условий в цикле while, чтобы проверить, заполнены ли поля, когда поток производителя должен ждать в коде производителя. но вывод у него другой, я запутался.

ошибка, когда я использую переменную с именем 'size', чтобы сохранить значение размера ящиков в коде выполнения потока. в некоторых случаях программа будет блокироваться как смерть.

Код производителя:

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();
                }
            }  
        }
    }
}

1 Ответ

4 голосов
/ 14 апреля 2019

Условие в операторе while в вашем текущем случае является статическим, т. Е. Для MAX_SIZE == size значение обеих переменных не изменяется при повторной оценке цикла while.

Когда notify вызывается boxes и поток производителя уведомляется, цикл while оценивается снова.Поскольку оба значения не изменились, оба будут иметь значение 5, и когда цикл будет оценен, его значение снова будет 5.Таким образом, условие будет 5==5, что приведет к повторному вызову wait.т.е. после входа в цикл while условие всегда будет true, что приведет к бесконечной блокировке.

Но с условием MAX_SIZE == boxes.size() значение boxes.size() является динамическим, и оно будетизменился, я думаю, по потребителю здесь.Допустим, потребитель удаляет один элемент из этого списка, так что boxes.size()=4 и он вызывает notify на boxes.Таким образом, поток производителя получает уведомление, и условие в producer становится 5 == 4, что приводит к тому, что условие составляет false, и выходит из цикла.Следовательно код выполняется как ожидалось

...