Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
# Метод notifyAll в Java
Метод notifyAll() определён в классе java.lang.Object — самом базовом классе Java.
Сигнатура метода
public final void notifyAll()
Этот метод:
- public — доступен всем
- final — не переопределяется
- void — ничего не возвращает
- Определён в классе Object
Что делает notifyAll()
Метод notifyAll() пробуждает все потоки, которые ждут на мониторе (блокировке) данного объекта.
public class WaitNotifyExample {
private static final Object lock = new Object();
private static boolean ready = false;
public static void main(String[] args) throws InterruptedException {
// Поток 1 — ждёт
Thread waiter = new Thread(() -> {
synchronized (lock) {
try {
System.out.println("Поток 1: начинаю ждать");
lock.wait(); // Ждёт уведомления
System.out.println("Поток 1: пробудился!");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
});
// Поток 2 — ждёт
Thread waiter2 = new Thread(() -> {
synchronized (lock) {
try {
System.out.println("Поток 2: начинаю ждать");
lock.wait(); // Ждёт уведомления
System.out.println("Поток 2: пробудился!");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
});
waiter.start();
waiter2.start();
Thread.sleep(1000);
// Поток 3 — уведомляет ВСЕ потоки
Thread notifier = new Thread(() -> {
synchronized (lock) {
System.out.println("Поток 3: отправляю notifyAll()");
lock.notifyAll(); // Пробудит ВСЕ ожидающие потоки
}
});
notifier.start();
notifier.join();
waiter.join();
waiter2.join();
}
}
Вывод:
Поток 1: начинаю ждать
Поток 2: начинаю ждать
Поток 3: отправляю notifyAll()
Поток 1: пробудился!
Поток 2: пробудился!
notify() vs notifyAll()
notify() — пробуждает ОДИН поток
synchronized (lock) {
lock.notify(); // Пробудит ОДНОГО из ожидающих
}
notifyAll() — пробуждает ВСЕ потоки
synchronized (lock) {
lock.notifyAll(); // Пробудит ВСЕХ ожидающих
}
Требования к использованию
- Вызов ТОЛЬКО внутри synchronized блока:
// ✅ Правильно
synchronized (lock) {
lock.notifyAll();
}
// ❌ Ошибка: IllegalMonitorStateException
lock.notifyAll(); // Без synchronized
- Поток должен владеть монитором объекта:
synchronized (obj) {
// Текущий поток владеет монитором obj
obj.notifyAll(); // OK
}
Когда использовать
notifyAll() используется в паттернах Producer-Consumer:
public class BlockingQueue<T> {
private final Queue<T> queue = new LinkedList<>();
private final int capacity;
public BlockingQueue(int capacity) {
this.capacity = capacity;
}
public synchronized void put(T item) throws InterruptedException {
while (queue.size() == capacity) {
wait(); // Ждёт, если очередь полная
}
queue.add(item);
notifyAll(); // Пробудит потребителей
}
public synchronized T take() throws InterruptedException {
while (queue.isEmpty()) {
wait(); // Ждёт, если очередь пустая
}
T item = queue.remove();
notifyAll(); // Пробудит производителей
return item;
}
}
Современная альтернатива
Вместо wait()/notify() лучше использовать java.util.concurrent:
// Вместо synchronized + wait/notify
private final Lock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();
public void waitForSignal() throws InterruptedException {
lock.lock();
try {
condition.await();
} finally {
lock.unlock();
}
}
public void signalWaiters() {
lock.lock();
try {
condition.signalAll(); // Аналог notifyAll()
} finally {
lock.unlock();
}
}
Вывод
notifyAll() — метод класса Object, используется для пробуждения всех потоков, ожидающих на мониторе. Требует вызова внутри synchronized блока. В современном коде рекомендуется использовать java.util.concurrent вместо wait/notify.