notify本质是单点唤醒信号器,用于避免忙等、节省CPU,需配合while循环和synchronized使用,适用于单消费者简单场景,不可脱离锁独立调用。

notify 方法在简易事件驱动系统中,本质是“单点唤醒信号器”:它不负责分发事件、不管理监听器列表、也不解析事件类型,而是作为底层线程协作的触发开关——当某个关键状态改变后,用它来唤醒一个正在等待该状态的线程,让其重新检查条件并决定是否响应事件。
它解决的核心问题:避免忙等,节省 CPU
在简易事件驱动场景(比如监控文件变化、轮询传感器数据、模拟按钮点击回调)中,若让工作线程不断循环检查“事件是否发生”,会持续占用 CPU。notify 配合 wait,能让线程真正挂起、释放锁、进入 WAITING 状态,直到被明确通知才苏醒。
- 例如:一个监听配置变更的后台线程,在配置未更新时调用
configObj.wait()挂起;当另一个线程修改完配置后,调用configObj.notify()—— 唤醒监听线程去加载新配置 - 注意:这里不是“通知具体哪个事件”,而是“有变化了,你自己去看看是什么”
它必须配合 while 循环和条件判断使用
notify 只是唤醒,并不保证条件已满足。可能因虚假唤醒、竞争或条件未真正就绪导致误执行。因此,等待逻辑必须写成循环结构:
- 错误写法:
if (event == null) wait();→ 一旦被唤醒就直接处理,风险高 - 正确写法:
while (event == null) wait();→ 唤醒后先重检条件,不满足继续等 - 这既是规范,也是应对多线程环境下状态不确定性的必要防护
它适合单消费者或低并发简单场景
notify 唤醒的是“任意一个”等待线程,不可控。在简易系统中,如果只有一个监听线程在等某类事件(如单个任务调度器、唯一状态观察者),用 notify 完全够用且轻量。
立即学习“Java免费学习笔记(深入)”;
- 优势:开销小,无需维护监听器集合,代码简洁
- 局限:如果有多个同类监听线程(如多个日志处理器都等“日志就绪”),notify 可能只唤醒其中一个,其余仍阻塞——此时应改用 notifyAll 或更合适的并发工具(如 BlockingQueue)
它不能脱离 synchronized 独立存在
notify 是对象监视器(monitor)的操作,必须由持有该对象锁的线程调用。这意味着事件通知和状态变更必须包裹在同一把锁下:
- 典型结构:修改共享状态 → 调用 notify → 退出同步块 → 等待线程才能重新抢到锁并继续
- 漏掉 synchronized 会抛出 IllegalMonitorStateException
- 锁对象要一致:wait 和 notify 必须作用于同一个对象实例



















