登录
首页 >  文章 >  java教程

notifyAll唤醒所有等待线程的使用方法

时间:2026-04-26 11:52:33 484浏览 收藏

`notifyAll()` 并非“一键唤醒并执行”,而只是将所有等待线程从等待集移入锁竞争队列,后续仍需严格同步——必须在同一个对象的 `synchronized` 块中调用,条件变量须受同一锁保护或声明为 `volatile`,且 `wait()` 必须置于 `while` 循环中以防虚假唤醒和条件过期;它不消除竞态,也不保证并发执行,反而可能因“惊群效应”拖累性能,因此多数场景下更推荐 `Condition`、`BlockingQueue` 等现代并发工具,仅在多条件依赖或无法精准唤醒时才谨慎使用。

如何使用notifyAll唤醒所有在对象监视器上等待的线程以竞争执行权

notifyAll 为什么不能直接“唤醒并执行”

notifyAll 的作用只是把所有在该对象上调用 wait() 而进入等待集(wait set)的线程,从等待状态移到**锁竞争队列**,而不是直接让它们继续执行。这些线程仍需重新竞争对象监视器(即 synchronized 锁),只有抢到锁的线程才能真正往下走;没抢到的会阻塞在 entry set,等锁释放后再次尝试。

常见误解是调用 notifyAll() 后所有线程立刻并发执行 —— 实际上它们仍被同步块/方法串行化约束,除非你显式设计成无锁或使用其他并发工具。

必须配合 while 循环检查条件,不能用 if

notifyAll() 唤醒的线程可能面临“虚假唤醒”(spurious wakeup),也可能因竞争失败而延迟获得锁,导致共享条件早已被其他线程修改。所以 wait() 必须放在 while 循环里,每次醒来都重新验证业务条件是否满足。

错误写法:

if (count == 0) { wait(); }
正确写法:
while (count == 0) { wait(); }
  • if 可能跳过条件检查,直接执行后续逻辑,引发 IllegalStateException 或数据错乱
  • 即使只唤醒一个线程(notify()),也推荐用 whilenotifyAll() 场景下更是强制要求
  • 条件变量(如 count)必须是 volatile 或受同一锁保护,否则可见性无法保证

notifyAll 必须在 synchronized 块内调用,且锁对象要一致

notifyAll()Object 的 final 方法,但它的语义依赖于当前线程持有该对象的监视器。如果不在 synchronized(obj) 块中调用,会抛出 IllegalMonitorStateException

典型错误:

synchronized(otherObj) {
    // 错误:this 和 otherObj 不是同一个锁
    this.notifyAll(); // 抛异常
}

正确做法:

synchronized (sharedLock) {
    count++;
    sharedLock.notifyAll(); // 必须和 wait() 使用同一个对象
}
  • wait / notifyAll 必须在同一个对象上配对使用,否则线程永远等不到唤醒
  • 避免用 this 作锁(易被外部误操作),优先用私有 final 对象,例如 private final Object lock = new Object();
  • 不要在循环体内部反复新建锁对象,会导致 notifyAll 失效

notifyAll 的实际适用场景和替代建议

notifyAll() 真正必要的场景其实不多:比如多个消费者等待不同类型的资源就绪、或生产者更新了多个条件变量、又或者你无法精确判断哪些线程该被唤醒(例如使用单一条件队列管理多种等待逻辑)。

多数情况下,更推荐:

  • java.util.concurrent 包下的高级工具,如 Condition(可绑定多个等待队列)、BlockingQueueSemaphore,它们语义清晰、不易出错
  • 若仅需唤醒一个等待者(如经典生产者-消费者单槽模型),notify() 更轻量,减少无谓竞争
  • 高并发下频繁 notifyAll() 可能引发“惊群效应”,大量线程争锁失败再挂起,徒增上下文切换开销

真正需要 notifyAll() 时,记得它不解决竞态,只负责“通知+重入竞争”,所有同步逻辑、条件检查、锁粒度控制,还得靠你自己兜底。

文中关于的知识介绍,希望对你的学习有所帮助!若是受益匪浅,那就动动鼠标收藏这篇《notifyAll唤醒所有等待线程的使用方法》文章吧,也可关注golang学习网公众号了解相关技术文章。

资料下载
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>