Методы wait и notify

386
06 января 2017, 09:21

В интернете нашел пример использования wait и notify:

public class ThreadsApp {
    public static void main(String[] args) {
        Store store = new Store();
        Producer producer = new Producer(store);
        Consumer consumer = new Consumer(store);
        new Thread(producer).start();
        new Thread(consumer).start();
    }
}
// Класс Магазин, хранящий произведенные товары
class Store {
    private int product = 0;
    private boolean available = false;
    public synchronized void get() {
        while (product < 1) {
            try {
                wait();
            } catch (InterruptedException e) {
            }
        }
        product--;
        System.out.println("Покупатель купил 1 товар");
        System.out.println("Товаров на складе: " + product);
        notify();
    }
    public synchronized void put() {
        while (product >= 3) {
            try {
                wait();
            } catch (InterruptedException e) {
            }
        }
        product++;
        System.out.println("Производитель добавил 1 товар");
        System.out.println("Товаров на складе: " + product);
        notify();
    }
}
// класс Производитель
class Producer implements Runnable {
    Store store;
    Producer(Store store) {
        this.store = store;
    }
    public void run() {
        for (int i = 1; i < 6; i++) {
            store.put();
        }
    }
}
// Класс Потребитель
class Consumer implements Runnable {
    Store store;
    Consumer(Store store) {
        this.store = store;
    }
    public void run() {
        for (int i = 1; i < 6; i++) {
            store.get();
        }
    }
}

Вопрос:

  1. В реализации методов get и put есть метод notify, который будит потоки, спящие на мониторе store, и это происходит каждый раз при их вызове, т.е. когда поток покупатель купил товар и вызвал notify в методе get, поток производитель на этом же мониторе УЖЕ ПРОСНУЛСЯ И ЖДЕТ ОСВОБОЖДЕНИЯ МОНИТОРА?

  2. Так как вызывается несколько раз notify, потому что вызывается несколько раз get и put, столько же раз происходит пробуждение потоков на мониторе, получается поток уже проснулся, и его еще 2 раза будят - как это с точки зрения правильности?

Answer 1
  1. notify - будит только 1 поток и не известно какой именно.
  2. Если никто не ждет, то notify ничего не делает.

Попробую пояснить подробно.

  1. Поток А захватывает lock и входит в синхронизированный код.
  2. Поток А вызывает wait, засыпает и освобождает lock.
  3. Поток Б захватывает lock и входит в синхронизированный код.
  4. Поток Б вызывает notify. Возможно (так как не известно какой поток будет разбужен) поток А просыпается становится в очередь на захват lock.
  5. Поток Б освобождает lock и выходит из синхронизированного кода.
  6. Поток А захватывает lock и продолжает со следующего после wait выражения.
READ ALSO
При каждом изменении кода и последующей компиляции выдает ошибку - Error:java: Cannot find JDK &#39;1.8&#39; for module &#39;MyProjects&#39;

При каждом изменении кода и последующей компиляции выдает ошибку - Error:java: Cannot find JDK '1.8' for module 'MyProjects'

Опять нужна помощьПри первом запуске только что написанного кода проблем нет

355
Библиотека для работы с изображениями JAVA

Библиотека для работы с изображениями JAVA

Требуется библиотека java для обработки изображенияТребуется возможность создания, попиксельного редактирования и сохранения изображения...

421
Walker_Nav_Menu вложенное меню

Walker_Nav_Menu вложенное меню

Мне нужно вложенное менюЯ переписал Walker_Nav_Menu

473