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

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

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

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

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

В многопоточном программировании в Java часто возникает необходимость синхронизировать доступ к общим ресурсам. Для этого используются мониторы, которые позволяют потокам координировать свои действия. Каждый объект в Java имеет монитор, и потоки могут "захватывать" этот монитор, чтобы получить эксклюзивный доступ к объекту.

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

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

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

public class SharedResource {
    private boolean isAvailable = false;
​
    public synchronized void produce() {
        isAvailable = true;
        // Уведомляем все ожидающие потоки, что ресурс теперь доступен
        notifyAll();
    }
​
    public synchronized void consume() throws InterruptedException {
        while (!isAvailable) {
            // Если ресурс недоступен, поток ждет
            wait();
        }
        // Потребление ресурса
        isAvailable = false;
    }
}
  • synchronized — ключевое слово, которое гарантирует, что только один поток может выполнять метод в одно и то же время, захватывая монитор объекта.
  • isAvailable — флаг, который указывает, доступен ли ресурс.
  • produce() — метод, который делает ресурс доступным и уведомляет все ожидающие потоки, что они могут проверить состояние ресурса.
  • notifyAll() — пробуждает все потоки, которые вызвали wait() на этом объекте, чтобы они могли проверить, изменилось ли состояние.
  • consume() — метод, который ждет, пока ресурс не станет доступным, и затем потребляет его. Если ресурс недоступен, поток вызывает wait(), освобождая монитор и переходя в состояние ожидания.

Использование notifyAll() вместо notify() (который пробуждает только один случайный поток) гарантирует, что все потоки получат возможность проверить состояние объекта, что особенно важно, если несколько потоков могут быть заинтересованы в изменении состояния.

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

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

Твои заметки