当前位置: 首页 > news >正文

为什么 wait() / notify() 必须在同步代码块 / 同步方法中调用

目录

一、先搞懂基础

二、核心原因(3 点)

1. 防止 丢失唤醒(Lost Wake-Up)(最关键)

错误时序(无锁场景)

加锁后(同步块),时序被原子化

2. JVM 语法强制:必须持有对象监视器

3. 保证等待 / 唤醒逻辑的线程安全

三、补充最佳实践(面试常考)

面试极简背诵版


一句话结论:为了规避「丢失唤醒」并发 bug,同时保证线程安全、语义合法,JVM 强制要求必须持有对象锁才能调用。

一、先搞懂基础

  1. wait()notify()notifyAll()Object 类方法,作用于对象监视器(锁)
  2. 调用obj.wait():当前线程释放 obj 锁,进入该对象的等待集阻塞,等待被唤醒。
  3. 调用obj.notify():随机唤醒等待集中一个线程;notifyAll()唤醒全部。

二、核心原因(3 点)

1. 防止丢失唤醒(Lost Wake-Up)(最关键)

这是设计层面的根本原因,先看不在同步块会出现的致命问题:

错误时序(无锁场景)

假设业务逻辑:条件不满足 → 等待;条件满足 → 唤醒

  1. 线程 A:判断条件不成立,正要执行wait()
  2. CPU 切换到线程 B
  3. 线程 B:修改数据,条件成立,执行notify()唤醒 →此时线程 A 还没进入等待队列,这次唤醒直接作废
  4. CPU 切回线程 A:继续执行wait()→ 线程 A 永久阻塞,永远没人再唤醒它(丢失唤醒)
加锁后(同步块),时序被原子化

锁保证「条件判断 + wait ()」是原子操作

  1. 线程 A 获取锁 → 判断条件不成立
  2. 直接执行wait()原子完成,中间不会被打断
  3. 线程 B 必须等 A 释放锁后才能进入、修改条件、notify 彻底杜绝「先唤醒、后等待」的丢失唤醒问题。

2. JVM 语法强制:必须持有对象监视器

JVM 规范规定:

调用wait()/notify()时,当前线程必须持有该 Object 的内置锁

如果没有持有锁直接调用,会立刻抛出:

java.lang.IllegalMonitorStateException

原因:

  • wait()语义是 **“拿着锁,主动放弃锁并等待”**;
  • 没有锁,就不存在「放弃锁」这个动作,语义不成立。

3. 保证等待 / 唤醒逻辑的线程安全

等待一般都伴随共享变量条件判断(比如队列空 / 满、状态标志):

  • 共享变量本身就存在并发竞争,必须加锁保证可见性、原子性
  • 同步块天然保证:变量状态在线程间及时可见,避免因指令重排、内存可见性导致逻辑错乱。

三、补充最佳实践(面试常考)

  1. wait()一定要放在while循环里防止虚假唤醒(线程可能在无 notify 时被意外唤醒):
    synchronized (obj) { while (条件不满足) { obj.wait(); } // 执行业务 }
  2. notify()/notifyAll()也必须在同一个对象锁的同步块中。
  3. 优先用notifyAll(),多数场景下更安全。

面试极简背诵版

  1. 防止丢失唤醒:锁让「条件判断 + wait」原子执行,避免唤醒先于等待发生;
  2. JVM 强制校验:调用这两个方法必须持有对象监视器,否则抛IllegalMonitorStateException
  3. 保证线程安全:同步锁保障条件变量的可见性与原子性。
http://www.jsqmd.com/news/925604/

相关文章:

  • 企业级Gemini生物识别集成成熟度评估矩阵(含12项等保2.0/GB/T 35273-2020对标项),仅开放前200份下载权限
  • 贝叶斯公式
  • 从 GitHub 到产线:MyEMS 开源能源管理系统在制造现场的部署实录
  • 戴森球计划终极工厂蓝图库:5000+免费设计让你轻松构建星际帝国
  • 2026浙江AI搜索优化服务商深度评测与选型指南 - 品牌报告
  • 腾讯云Windows服务器上,如何彻底关闭Microsoft Defender SmartScreen的烦人弹窗?(附三种方法对比)
  • 从零搭建本地RAG知识库,你的文档终于能自己回答问题了!从安装到测试全流程讲解!
  • 2026 屋面露台防水综合排行榜 苏易修缮防水全域应急抢修连锁评选 - 吉修匠
  • 解放你的音乐收藏:ncmdumpGUI让网易云音乐NCM文件随处播放的终极指南
  • 合肥理工学校招生办电话号码是多少?官网最新发布! - 教育为先
  • 深入瑞芯微RK3568 BSP:从Android.bp到u-boot.img,带你读懂原厂SDK的目录结构与编译产物
  • 2026苏州卫生间漏水免砸砖维修 本地防水堵漏权威测评口碑优选商家 - 吉修匠
  • dSPACE安装后,如何快速完成上位机与MicroAutoBOX II的联调?一个案例讲透网络配置与平台注册
  • windows11 C盘文件过大清理方法汇总
  • 基于 Harmony 6.0 应用的宠物寄养预约系统实现
  • Linux文件‘捉迷藏’实战:5分钟掌握find与grep的日常高效用法(附场景案例)
  • 如何用Video2X免费AI视频增强工具让模糊视频变高清:完整实战指南
  • 终极D2DX宽屏补丁:如何让经典《暗黑破坏神2》在现代PC上完美运行
  • 告别电源‘打嗝’:一个恒流电路如何根治RCC的间歇振荡难题?
  • 保姆级教程:用HACS给追觅扫地机装上Home Assistant大脑,告别App切换
  • 大数据驱动传统行业变革:医疗、法律、零售的实战解析与核心技术栈
  • 为什么你的Gemini系统在黑产攻击高峰仍漏判23%高危交易?——头部支付机构内部攻防复盘报告
  • 2026年安徽省初三成绩在300分左右适合上什么学校?——推荐合肥理工学校 - 教育为先
  • 合肥理工学校招生办电话号码是多少?2026年官网最新发布! - 教育为先
  • 合肥市初三毕业生考不上高中适合上什么学校?——最新发布推荐学校一览 - 教育为先
  • 合肥市哪所中专学校升学率最高?——合肥理工学校 - 教育为先
  • Arduino Nano一体化扩展板设计:集成电源管理与多电机驱动实战
  • 客制化键盘改造:3D打印拇指扩展键,提升输入效率与人体工学体验
  • Win-PS2EXE:3步快速将PowerShell脚本编译成EXE的终极图形化工具
  • 技术重塑就业市场:未来五年AI、大数据与数字化技能需求分析