Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Java Новый топик    Ответить
 Не понимаю пример из книги  [new]
ambrazoura
Member

Откуда:
Сообщений: 2
Здравствуйте, читаю Шилдта, главу про многопоточность, там есть пример на wait(), notify(). Хотел разобраться как они работают, а в итоге появилось ещё больше вопросов. Сам пример из книги:
class Q {
    int n;
    boolean valueSet = false;
    
    synchronized int get() {
        while(!valueSet)
            try {
                wait();
            } catch(InterruptedException e) {
                System.out.println("Исключение типа InterruptedException перехвачено");
            }
        
        System.out.println("Получено: " + n);
        valueSet = false;
        notify();
        return n;   
    }
synchronized void put(int n) {
        while(valueSet) {
            try {
                wait();
            } catch(InterruptedException e) {
                System.out.println("Исключение типа InterruptedException перехвачено");
            }
            
            this.n = n;
            valueSet = true;
            System.out.println("Отправлено: " + n);
            notify();
        }
    }
}
class Producer implements Runnable {
    Q q;
    
    Producer(Q q) {
        this.q = q;
        new Thread(this, "Поставщик").start();
    }
    
    public void run() {
        int i = 0;
        
        while(true) {
            q.put(i++);
        }
    }
}

class Consumer implements Runnable {
    Q q;
    
    Consumer(Q q) {
        this.q = q;
        new Thread(this, "Потребитель").start();
    }
    
    public void run() {
        while(true) {
            q.get();
        }
    }
}
public class PC {
 
    public static void main(String[] args) {
    
        Q q = new Q();
        new Producer(q);
        new Consumer(q);
        
        System.out.println("Для остановки нажмите Ctrl-C.");
 
    }
 
}

Обьясните, пожалуйста, на пальцах, как это всё работает. Мы от Producer заходим в put и тут же вызываем wait. По идее поток Producer должен остановиться, судя из описания метода, но этого не происходит, почему? Из этого когда мне казалось, что оба потока так и зависнут на wait и будут ждать друг друга.
18 апр 20, 14:38    [22118444]     Ответить | Цитировать Сообщить модератору
 Re: Не понимаю пример из книги  [new]
chpasha
Member

Откуда:
Сообщений: 9222
сам-то пример пробовал для начала запустить, ну чтобы убедиться, что там все верно? у тебя ошибка в коде, либо опечатка в книжке - в методе put цикл while должен содержать только кусок try-catch, а не весь блок
synchronized void put(int n) {
            while (valueSet) {
                try {
                    wait();
                }
                catch (InterruptedException e) {
                    System.out.println("Исключение типа InterruptedException перехвачено");
                }
            }
            this.n = n;
            valueSet = true;
            System.out.println("Отправлено: " + n);
            notify();

        }

тогда все правильно - т.к. valueSet == false, метод get входит в ожидание по wait, а вот put минуя wait устанавливает первое значение, и оповещает через notify get, а сам на следующей итерации переходит в свою очередь в wait, пока не получит notify от get
18 апр 20, 15:18    [22118467]     Ответить | Цитировать Сообщить модератору
 Re: Не понимаю пример из книги  [new]
ambrazoura
Member

Откуда:
Сообщений: 2
chpasha
сам-то пример пробовал для начала запустить, ну чтобы убедиться, что там все верно? у тебя ошибка в коде, либо опечатка в книжке - в методе put цикл while должен содержать только кусок try-catch, а не весь блок

ПК сейчас нет под рукой, поэтому не было возможности запустить код.

Теперь стало более менее ясно.
18 апр 20, 15:32    [22118474]     Ответить | Цитировать Сообщить модератору
Все форумы / Java Ответить