← Назад ко всем вопросам

Зачем нужен метод notify() из класса Object

1️⃣ Как кратко ответить

Метод notify() из класса Object используется для возобновления работы одного из потоков, который ожидает на мониторе объекта. Он уведомляет один случайно выбранный поток, ожидающий на этом мониторе, что монитор теперь доступен.

2️⃣ Подробное объяснение темы

В многопоточной среде Java потоки могут взаимодействовать друг с другом через механизмы синхронизации. Одним из таких механизмов является использование методов wait(), notify(), и notifyAll() из класса Object. Эти методы позволяют потокам координировать свои действия, используя монитор объекта.

Зачем нужен метод notify()

Метод notify() используется для управления потоками, которые ожидают на мониторе объекта. Когда поток вызывает wait() на объекте, он освобождает монитор этого объекта и переходит в состояние ожидания. Другие потоки могут захватить монитор и выполнить свою работу. Когда поток завершает свою работу и хочет уведомить один из ожидающих потоков о том, что монитор снова доступен, он вызывает метод notify().

Как это работает

  1. Монитор и блокировка: Каждый объект в Java имеет монитор, который может быть захвачен потоком. Когда поток входит в синхронизированный блок или метод, он захватывает монитор объекта.

  2. Ожидание потока: Поток, который вызывает wait(), освобождает монитор и переходит в состояние ожидания. Он будет ждать, пока другой поток не вызовет notify() или notifyAll() на том же объекте.

  3. Уведомление потока: Когда поток вызывает notify(), один из потоков, ожидающих на мониторе объекта, будет пробужден. Однако пробужденный поток не может сразу продолжить выполнение. Он должен дождаться, пока текущий поток освободит монитор.

Пример использования

Рассмотрим пример, где один поток производит данные, а другой поток их потребляет. Они используют общий объект для синхронизации.

class Data {
    private String packet;
    private boolean transfer = true;
​
    // Метод для получения данных
    public synchronized String receive() {
        while (transfer) {
            try {
                wait(); // Ожидание, пока данные не будут готовы
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                System.out.println("Thread interrupted");
            }
        }
        transfer = true;
        notify(); // Уведомление потока-производителя о том, что данные получены
        return packet;
    }
​
    // Метод для отправки данных
    public synchronized void send(String packet) {
        while (!transfer) {
            try {
                wait(); // Ожидание, пока данные не будут получены
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                System.out.println("Thread interrupted");
            }
        }
        transfer = false;
        this.packet = packet;
        notify(); // Уведомление потока-потребителя о том, что данные отправлены
    }
}
  • Класс Data: содержит методы send и receive для отправки и получения данных.
  • Метод send: поток, вызывающий этот метод, ждет, пока данные не будут получены (transfer равно false). После отправки данных он вызывает notify(), чтобы разбудить поток, ожидающий получения данных.
  • Метод receive: поток, вызывающий этот метод, ждет, пока данные не будут готовы (transfer равно true). После получения данных он вызывает notify(), чтобы разбудить поток, ожидающий отправки данных.

Применение

Метод notify() полезен в ситуациях, где необходимо координировать работу нескольких потоков, чтобы избежать состояния гонки и обеспечить корректное выполнение программы. Он позволяет эффективно управлять доступом к общим ресурсам, минимизируя время ожидания потоков.

Тема: ООП
Стадия: Tech

🔒 Подпишись на бусти автора и стань Алигатором, чтобы получить полный доступ к функционалу сайта и отслеживать свой прогресс!

Твои заметки