在 java 的 synchronized 块中,notifyall() 方法用于唤醒所有在该对象监视器上等待的线程。调用此方法后,这些线程会进入竞争锁的状态,只有获取到锁的线程才能继续执行后续代码。

notifyAll() 与 notify() 的核心区别是什么
notifyAll() 会唤醒所有等待线程,而 notify() 仅随机唤醒一个。使用 notifyAll() 可以避免因唤醒错误线程导致的死锁或逻辑遗漏,是更安全的做法。

public class NotifyAllDemo {
private static final Object lock = new Object();
private static boolean ready = false;
public static void main(String[] args) throws InterruptedException {
Thread waiter = new Thread(() -> {
synchronized (lock) {
while (!ready) {
try { lock.wait(); } catch (InterruptedException e) {}
}
System.out.println("Waiter: Ready!");
}
});
waiter.start();
Thread.sleep(100);
synchronized (lock) {
ready = true;
lock.notifyAll(); // 唤醒所有等待者
}
waiter.join();
}
}为什么必须配合 while 循环检查条件
即使使用了 notifyAll(),线程被唤醒后也必须重新检查条件。因为可能存在多个线程同时被唤醒,但只有一个能获取锁并改变状态的情况,其他线程需要再次进入等待。
立即学习“Java免费学习笔记(深入)”;

public class WhileLoopCheck {
private static final Object lock = new Object();
private static int count = 0;
public static void producer() throws InterruptedException {
synchronized (lock) {
while (count >= 10) { lock.wait(); }
count++;
lock.notifyAll();
}
}
public static void consumer() throws InterruptedException {
synchronized (lock) {
while (count <= 0) { lock.wait(); }
count--;
lock.notifyAll();
}
}
}notifyAll() 在多线程生产者-消费者模型中的具体表现
在生产者-消费者场景中,notifyAll() 能确保所有等待的生产者和消费者都被唤醒去检查队列状态。这防止了某些线程永远不被唤醒的风险,尽管这会带来一定的性能开销(惊群效应),但在正确性上是必要的。


















