news 2026/3/8 1:20:01

Java面试必看:notify()与notifyAll区别?点睛之笔!

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java面试必看:notify()与notifyAll区别?点睛之笔!

文章目录

  • Java面试必看:notify()与notifyAll区别?点睛之笔!
    • 引言
    • 什么是 notify() 和 notifyAll()
      • 基本概念
    • 为什么会有 notify() 和 notifyAll()?
    • notify() 和 notifyAll() 的核心区别
      • 1. 唤醒范围不同
        • `notify()`:只唤醒一个线程
        • `notifyAll()`:唤醒所有线程
      • 2. 使用场景不同
        • `notify()` 的适用场景
        • `notifyAll()` 的适用场景
      • 3. 性能考虑
      • 4. 注意事项
      • 总结
    • 在实际开发中,合理选择 `notify()` 和 `notifyAll()` 对系统的性能和稳定性有重要影响。
      • 📚 领取 | 1000+ 套高质量面试题大合集(无套路,闫工带你飞一把)!

Java面试必看:notify()与notifyAll区别?点睛之笔!

引言

大家好,我是闫工,今天我们要聊一个Java面试中经常被问到的考点——notify()notifyAll()的区别。这两个方法在多线程编程中非常重要,但它们的区别却常常让人一头雾水。别担心,我会用轻松幽默的方式为你详细解析,保证让你一学就会!


什么是 notify() 和 notifyAll()

在Java中,线程之间的通信离不开通知机制,而notify()notifyAll()就是实现这种机制的两个关键方法。它们都属于Object类,因此任何对象都可以调用这两个方法。

基本概念

  • notify(): 这个方法会唤醒一个正在等待该对象监视器的线程。
  • notifyAll(): 这个方法会唤醒所有正在等待该对象监视器的线程。

简单来说,notify()是“点名”叫醒某一个线程,而notifyAll()则是“广撒网”,把所有睡着的线程都叫醒。


为什么会有 notify() 和 notifyAll()?

在线程编程中,我们经常需要多个线程协作完成任务。比如生产者-消费者模型:一个或多个生产者线程负责生成数据,一个或多个消费者线程负责消费数据。如果没有通知机制,这些线程可能会陷入“忙等”状态,导致性能低下甚至死锁。

notify()notifyAll()的作用就是让线程之间能够高效地通信。通过它们,我们可以控制哪些线程被唤醒,从而优化程序的执行效率。


notify() 和 notifyAll() 的核心区别

1. 唤醒范围不同

notify():只唤醒一个线程

notify()会随机选择一个正在等待该对象监视器的线程,并将其唤醒。剩下的线程仍然保持阻塞状态,直到再次被通知或中断。

示例代码:

publicclassNotifyExample{publicstaticvoidmain(String[]args){Objectlock=newObject();// 创建多个线程for(inti=0;i<5;i++){newThread(()->{synchronized(lock){System.out.println(Thread.currentThread().getName()+" 进入等待状态");try{lock.wait();}catch(InterruptedExceptione){e.printStackTrace();}System.out.println(Thread.currentThread().getName()+" 被唤醒");}}).start();}// 主线程通知newThread(()->{synchronized(lock){try{Thread.sleep(2000);}catch(InterruptedExceptione){e.printStackTrace();}System.out.println("主线程调用 notify()");lock.notify();// 只唤醒一个线程}}).start();}}

运行结果:

Thread-0 进入等待状态 Thread-1 进入等待状态 Thread-2 进入等待状态 Thread-3 进入等待状态 Thread-4 进入等待状态 主线程调用 notify() Thread-0 被唤醒

从结果可以看出,notify()只唤醒了一个线程(比如Thread-0),其他线程仍然处于阻塞状态。

notifyAll():唤醒所有线程

notifyAll()会将所有正在等待该对象监视器的线程都唤醒。这通常用于需要让所有线程继续执行的情况。

示例代码:

publicclassNotifyAllExample{publicstaticvoidmain(String[]args){Objectlock=newObject();// 创建多个线程for(inti=0;i<5;i++){newThread(()->{synchronized(lock){System.out.println(Thread.currentThread().getName()+" 进入等待状态");try{lock.wait();}catch(InterruptedExceptione){e.printStackTrace();}System.out.println(Thread.currentThread().getName()+" 被唤醒");}}).start();}// 主线程通知newThread(()->{synchronized(lock){try{Thread.sleep(2000);}catch(InterruptedExceptione){e.printStackTrace();}System.out.println("主线程调用 notifyAll()");lock.notifyAll();// 唤醒所有线程}}).start();}}

运行结果:

Thread-0 进入等待状态 Thread-1 进入等待状态 Thread-2 进入等待状态 Thread-3 进入等待状态 Thread-4 进入等待状态 主线程调用 notifyAll() Thread-0 被唤醒 Thread-1 被唤醒 Thread-2 被唤醒 Thread-3 被唤醒 Thread-4 被唤醒

从结果可以看出,notifyAll()唤醒了所有线程。


2. 使用场景不同

notify()的适用场景

notify()适用于只需要唤醒一个线程的场景。例如:

  • 单生产者-多消费者模型:当一个生产者生成数据后,只需要通知一个消费者来处理。
  • 需要控制资源竞争的场景。

示例代码:

publicclassProducerConsumer{privateObjectlock=newObject();privatebooleanhasProduct=false;publicvoidproduce(){synchronized(lock){if(hasProduct){try{lock.wait();// 等待消费者消费}catch(InterruptedExceptione){e.printStackTrace();}}System.out.println("生产者生产了产品");hasProduct=true;lock.notify();// 唤醒一个消费者}}publicvoidconsume(){synchronized(lock){if(!hasProduct){try{lock.wait();// 等待生产者生产}catch(InterruptedExceptione){e.printStackTrace();}}System.out.println("消费者消费了产品");hasProduct=false;lock.notify();// 唤醒一个生产者}}publicstaticvoidmain(String[]args){ProducerConsumerpc=newProducerConsumer();// 创建多个消费者线程for(inti=0;i<3;i++){newThread(()->pc.consume()).start();}// 创建生产者线程newThread(()->{while(true){pc.produce();try{Thread.sleep(1000);}catch(InterruptedExceptione){e.printStackTrace();}}}).start();}}
notifyAll()的适用场景

notifyAll()适用于需要唤醒所有线程的场景。例如:

  • 所有线程都需要重新竞争资源。
  • 广播通知:比如某个条件满足后,所有线程都可以继续执行。

示例代码:

publicclassBroadcastExample{privateObjectlock=newObject();publicvoidcheckCondition(){synchronized(lock){System.out.println(Thread.currentThread().getName()+" 进入检查");if(!conditionMet()){// 假设条件未满足try{lock.wait();}catch(InterruptedExceptione){e.printStackTrace();}}System.out.println(Thread.currentThread().getName()+" 条件满足,继续执行");}}publicvoidnotifyAllThreads(){synchronized(lock){System.out.println("设置条件为已满足");conditionMet();// 假设条件已满足lock.notifyAll();// 通知所有线程}}privatebooleanconditionMet(){returntrue;// 简化逻辑,假设条件已满足}publicstaticvoidmain(String[]args){BroadcastExampleexample=newBroadcastExample();// 创建多个检查线程for(inti=0;i<3;i++){newThread(()->example.checkCondition()).start();}// 主线程设置条件并通知所有线程newThread(()->example.notifyAllThreads()).start();}}

3. 性能考虑

  • notify()的性能更高,因为它只唤醒一个线程。
  • notifyAll()的性能较低,因为它需要唤醒多个线程。

因此,在大多数情况下,优先使用notify();只有在确实需要唤醒所有线程时才使用notifyAll()


4. 注意事项

  • 在调用wait()notify()方法时,必须持有同一对象的锁。
  • wait()必须在同步块中调用,否则会抛出IllegalMonitorStateException
  • 使用wait()notify()需要特别注意避免死锁和资源竞争问题。

总结

特性notify()notifyAll()
唤醒线程数1所有
使用场景单个唤醒广播通知
性能较低
资源竞争控制更好较差

在实际开发中,合理选择notify()notifyAll()对系统的性能和稳定性有重要影响。

📚 领取 | 1000+ 套高质量面试题大合集(无套路,闫工带你飞一把)!

成体系的面试题,无论你是大佬还是小白,都需要一套JAVA体系的面试题,我已经上岸了!你也想上岸吗?

闫工精心准备了程序准备面试?想系统提升技术实力?闫工精心整理了1000+ 套涵盖前端、后端、算法、数据库、操作系统、网络、设计模式等方向的面试真题 + 详细解析,并附赠高频考点总结、简历模板、面经合集等实用资料!

✅ 覆盖大厂高频题型
✅ 按知识点分类,查漏补缺超方便
✅ 持续更新,助你拿下心仪 Offer!

📥免费领取👉 点击这里获取资料

已帮助数千位开发者成功上岸,下一个就是你!✨

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/5 15:43:46

Axure RP全系列中文界面快速配置终极手册

Axure RP全系列中文界面快速配置终极手册 【免费下载链接】axure-cn Chinese language file for Axure RP. Axure RP 简体中文语言包&#xff0c;不定期更新。支持 Axure 9、Axure 10。 项目地址: https://gitcode.com/gh_mirrors/ax/axure-cn 还在为Axure RP的英文界面…

作者头像 李华
网站建设 2026/3/6 6:10:42

告别平台切换烦恼!OBS多平台推流插件一键同步直播全攻略

告别平台切换烦恼&#xff01;OBS多平台推流插件一键同步直播全攻略 【免费下载链接】obs-multi-rtmp OBS複数サイト同時配信プラグイン 项目地址: https://gitcode.com/gh_mirrors/ob/obs-multi-rtmp 还在为不同平台的直播设置而头疼吗&#xff1f;想要同时覆盖抖音、B…

作者头像 李华
网站建设 2026/2/27 9:37:33

Jellyfin个性化定制终极指南:打造专属智能媒体中心

Jellyfin个性化定制终极指南&#xff1a;打造专属智能媒体中心 【免费下载链接】awesome-jellyfin A collection of awesome Jellyfin Plugins, Themes. Guides and Companion Software (Not affiliated with Jellyfin) 项目地址: https://gitcode.com/gh_mirrors/aw/awesome…

作者头像 李华
网站建设 2026/3/4 3:41:32

MuJoCo闭环机构约束问题实战:从崩溃到稳定的工程笔记

MuJoCo闭环机构约束问题实战&#xff1a;从崩溃到稳定的工程笔记 【免费下载链接】mujoco Multi-Joint dynamics with Contact. A general purpose physics simulator. 项目地址: https://gitcode.com/GitHub_Trending/mu/mujoco 崩溃现场&#xff1a;我的第一次闭环机构…

作者头像 李华
网站建设 2026/3/2 2:40:05

《精通 Python 设计模式:从入门理解到实战落地》

《精通 Python 设计模式&#xff1a;从入门理解到实战落地》“设计模式不是银弹&#xff0c;但它是你代码世界的地图。”——写给每一位渴望写出优雅、可维护代码的 Python 开发者一、引言&#xff1a;为什么 Python 程序员也需要设计模式&#xff1f; 在 Python 这样一门灵活、…

作者头像 李华
网站建设 2026/3/5 18:45:36

《Python 工厂模式全解析:从设计理念到实战落地》

《Python 工厂模式全解析&#xff1a;从设计理念到实战落地》“当你不想在代码中写死类名时&#xff0c;工厂模式就是你的朋友。”——写给每一位追求灵活架构与可扩展性的 Python 开发者一、引言&#xff1a;对象创建的隐性复杂性 在软件开发中&#xff0c;“创建对象”看似简…

作者头像 李华