【JavaEE】多线程(3) -- 线程等待 wait 和 notify

目录
1. wait()⽅法
2. notify()⽅法
3. notifyAll()⽅法
4. wait 和 sleep 的对⽐(⾯试题)
由于线程之间是抢占式执⾏的, 因此线程之间执⾏的先后顺序难以预知. 但是实际开发中有时候我们希望合理的协调多个线程之间的执⾏先后顺序.
完成这个协调⼯作, 主要涉及到三个⽅法
- wait() / wait(long timeout): 让当前线程进⼊等待状态.
- notify() / notifyAll(): 唤醒在当前对象上等待的线程.
注意: wait, notify, notifyAll 都是 Object 类的⽅法
1. wait()⽅法
wait 做的事情:
• 使当前执⾏代码的线程进⾏等待. (把线程放到等待队列中)
• 释放当前的锁
• 满⾜⼀定条件时被唤醒, 重新尝试获取这个锁.
wait 要搭配 synchronized 来使⽤. 脱离 synchronized 使⽤ wait 会直接抛出异常.

wait 结束等待的条件:
• 其他线程调⽤该对象的 notify ⽅法.
• wait 等待时间超时 (wait ⽅法提供⼀个带有 timeout 参数的版本, 来指定等待时间).
• 其他线程调⽤该等待线程的 interrupted ⽅法, 导致 wait 抛出 InterruptedException 异常.
public class Test {public static void main(String[] args) {Object locker = new Object();Thread t = new Thread(()->{synchronized (locker) {System.out.println("wait 等待之前");try {locker.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("wait 等待结束");}});t.start();}
}

这样在执⾏到 object.wait() 之后就⼀直等待下去,那么程序肯定不能⼀直这么等待下去了。这个时候就 需要使⽤到了另外⼀个⽅法唤醒的⽅法 notify()。
wait提供了两个版本:

2. notify()⽅法
notify ⽅法是唤醒等待的线程.
- ⽅法notify()也要在同步⽅法或同步块中调⽤,该⽅法是⽤来通知那些可能等待该对象的对象锁的其 它线程,对其发出通知notify,并使它们重新获取该对象的对象锁。
- 如果有多个线程等待,则有线程调度器随机挑选出⼀个呈 wait 状态的线程。(并没有 "先来后到")
- 在notify()⽅法后,当前线程不会⻢上释放该对象锁,要等到执⾏notify()⽅法的线程将程序执⾏ 完,也就是退出同步代码块之后才会释放对象锁
notify 其实可以不放到 synchronize 里, 不需要先加锁, 但是 java 中特别约定要把 notify 放到 synchronized 里.
代码⽰例: 使⽤notify()⽅法唤醒线程
public class Test {public static void main(String[] args) throws InterruptedException {Object locker = new Object();Thread t1 = new Thread(()->{synchronized (locker) {System.out.println("t1 wait 之前");try {locker.wait();}catch (InterruptedException e) {e.printStackTrace();}System.out.println("t1 wait 之后");}});Thread t2 = new Thread(()-> {try {Thread.sleep(3000);//让 t1 线程有时间进入到wait状态synchronized (locker) {System.out.println("t2 notify 之前");locker.notify();System.out.println("t2 notify 之后");}}catch (InterruptedException e) {e.printStackTrace();}});t1.start();t2.start();}
}


wait 和 notify 彼此之间是通过 Object 对象联系起来的, 必须是两个对象一致时才能够被唤醒.
3. notifyAll()⽅法
notify⽅法只是唤醒某⼀个等待线程. 使⽤notifyAll⽅法可以⼀次唤醒所有的等待线程.
理解 notify 和 notifyAll
notify 只唤醒等待队列中的⼀个线程. 其他线程还是乖乖等着
notifyAll ⼀下全都唤醒, 需要这些线程重新竞争锁
4. wait 和 sleep 的对⽐(⾯试题)
1. wait 需要搭配 synchronized 使⽤. sleep 不需要.
2. wait 是 Object 的⽅法 sleep 是 Thread 的静态⽅法.

在Java中,
wait()和sleep()都是用于线程控制的方法,但是它们有一些重要的区别。
wait()是Object类中定义的方法,而sleep()是Thread类中定义的方法。wait()是在对象级别上进行操作,而sleep()是在当前线程级别上进行操作。
wait()方法会释放线程持有的锁,使线程进入等待状态,直到其他线程调用相同对象上的notify()或notifyAll()方法来唤醒等待的线程。sleep()方法不会释放线程持有的锁。
wait()方法必须在同步上下文中被调用,即在同步方法或同步块中,否则会抛出IllegalMonitorStateException异常。而sleep()方法可以在任何地方调用。
wait()方法还可以指定一个超时时间,在等待超时后会自动唤醒线程。而sleep()方法只能通过interrupt()方法或等待指定时间来唤醒线程。总的来说,
wait()方法用于线程间的协调和通信,而sleep()方法主要用于线程的休眠。wait()方法在等待期间会释放锁,而sleep()方法不会释放锁。

相关文章:
【JavaEE】多线程(3) -- 线程等待 wait 和 notify
目录 1. wait()⽅法 2. notify()⽅法 3. notifyAll()⽅法 4. wait 和 sleep 的对⽐(⾯试题) 由于线程之间是抢占式执⾏的, 因此线程之间执⾏的先后顺序难以预知. 但是实际开发中有时候我们希望合理的协调多个线程之间的执⾏先后顺序. 完成这个协调⼯…...
自行编写一个简单的shell!
本文旨在编写一个简单的shell外壳程序!功能类似于shell的一些基本操作!虽然不能全部实现shell的一些功能!但是通过此文章,自己写一个简单的shell程序也是不成问题!并且通过此文章,可以让读者对linux中一些环…...
mvn site 命令
概述 在Maven中,site指的是一个特定的阶段,其目的是生成项目相关的站点文档。这些站点文档可以为项目的开发者、用户、以及其他利益相关者提供有关项目的详细信息。 Maven的站点文档通常包括以下内容: 项目信息:这部分提供了关于…...
<JavaEE> 经典设计模式之 -- 定时器
目录 一、定时器的概念 二、Java 标准库中的定时器 三、实现自己的定时器 一、定时器的概念 什么是定时器?定时器是软件开发中的一个常用且重要组件,作用是在达到设定时间后,执行指定的代码。 二、Java 标准库中的定时器 1)T…...
【C++ Primer Plus学习记录】if语句
目录 一、if语句 二、if else语句 三、格式化if else语句 四、if else if else结构 一、if语句 if语句让程序能够决定是否应执行特定的语句。 if有两种格式:if和if else。 if语句的语法与while相似: if(test-condition)statement; 如果test-con…...
结构体,自定义类型
目录 结构体 结构体的声明 结构体的自引用 结构体的定义和初始化 结构体内存对齐 编辑 结构体的对齐规则: 为什么存在内存对齐? 修改默认对齐数 结构体传参 位段 什么是位段 位段的内存分配 位段的跨平台问题 枚举 联合(共用体…...
Ubuntu22.04通过Maas和Juju部署openstack charm
目录 官方文档材料准备软件硬件 模板机和虚拟网络安装MAAS官方文档MAAS节点配置安装MAAS浏览器登录MAAS进行配置 激活DHCP 官方文档 https://docs.openstack.org/project-deploy-guide/charm-deployment-guide/2023.1/ 这是一个通过Maas面板即可部署openstack的方式࿰…...
老有所依:TSINGSEE青犀养老院智能视频监管方案
养老院智能监控方案是为了提高养老院内老人的安全和护理质量,利用智能技术与监控设备进行全方位的监控和管理,可以加强对老人的监护和护理,提高养老院的服务质量和安全性。 旭帆科技基于视频技术与AI智能分析技术构建的养老院智能视频监控方…...
vue中的this.$nextTick().then()
MENU 示例一示例二sortsplicepushrandomfloorMathwhile演示 示例一 let reorganize function (arr){let rest [];while (arr.length > 0) {let random Math.floor(Math.random() * arr.length);// 把获取到的值放到新定义的数组中rest.push(arr[random]);// 这句代码的作…...
Python处理Excel文件并与数据库匹配做拼接
Python处理Excel文件并与数据库匹配做拼接 需求:Python处理Excel中数据并于数据库交互匹配得到账号信息等其他操作 Python实现 import os import pandas as pd import pymssql import warnings import time# 提取速率函数 def extract_broadband_speed(speed):if…...
【出现模块node_modules里面包找不到】
#pic_center R 1 R_1 R1 R 2 R^2 R2 目录 一、出现的问题二、解决办法三、其它可供参考 一、出现的问题 在本地运行 npm run docs:dev之后,出现 Error [ERR_MODULE_NOT_FOUND]: Cannot find package Z:\Blog\docs\node_modules\htmlparser2\ imported from Z:\Blo…...
高项备考葵花宝典-项目进度管理输入、输出、工具和技术(中,很详细考试必过)
项目进度管理的目标是使项目按时完成。有效的进度管理是项目管理成功的关键之一,进度问题在项目生命周期内引起的冲突最多。 小型项目中,定义活动、排列活动顺序、估算活动持续时间及制定进度模型形成进度计划等过程的联系非常密切,可以视为一…...
sql注入 [GXYCTF2019]BabySQli1
打开题目 多次尝试以后我们发现存在一个admin的账号,但是密码我们不知道 我们尝试一下万能密码 admin or 11 -- q 报错 我们尝试bp抓一下包看看 看着很像编码 先去base32解码 再base64解码 得到 我们从这个sql语句中得到注入点为name 根据报错信息我们知道是…...
python二维数组创建赋值问题:更改单个值却更改了所有项的值
test_list [] dic1 {} test_list [dic1 for _ in range(3)] ll [1, 2, 3]for i in range(3):test_list[i][value] ll[i]print(test_list)运行结果:每次赋值都更改了所有项 原因:python的二位数据创建方式就是这样,官方文档中有描述Wha…...
深度模型训练时CPU或GPU的使用model.to(device)
一、使用device控制使用CPU还是GPU device torch.device("cuda:0" if torch.cuda.is_available() else "cpu") # 单GPU或者CPU.先判断机器上是否存在GPU,没有则使用CPU训练 model model.to(device) data data.to(device)#或者在确定有GPU的…...
SpringBoot3-实现和注册拦截器
1、pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.…...
Ubuntu 22.04源码安装yasm 1.3.0
sudo lsb_release -r看到操作系统的版本是22.04,sudo uname -r可以看到内核版本是5.15.0-86-generic,sudo gcc --version可以看到版本是11.2.0,sudo make --version可以看到版本是GNU Make 4.3。 下载yasm http://yasm.tortall.net/Downlo…...
LeetCode [中等]矩阵置零
73. 矩阵置零 - 力扣(LeetCode) 暴力解法 用两个标记数组分别记录每一行和每一列是否有零出现。 遍历该数组一次,如果某个元素为 0,那么就将该元素所在的行和列所对应标记数组的位置置为 true。再次遍历该数组,用标…...
十一、了解分布式计算
1、什么是(数据)计算? 2、分布式(数据)计算 (1)概念 顾名思义,分布式计算,即以分布式的形式完成数据的统计,得到需要的结果。 分布式数据计算,顾名思义,就是…...
数据结构和算法专题---2、算法思想
上文讲到算法的概念、复杂度,本文给大家介绍具体的算法思想,让大家对算法设计理念有个认识,后续再分别介绍各种算法。 算法思想 算法是解决问题的一种思想和方法,其基本思想是将一个复杂问题分解为多个简单的子问题,…...
上海计算机学会2026年2月月赛C++丙组T1 乘积的秘密
乘积的秘密 题目描述 给定两个整数 A 与 B,保证 A ≤ B。请求出从 A 一直乘到 B 的符号: 如果乘积大于 0,输出 Positive;如果乘积小于 0,输出 Negative;如果乘积等于 0,输出 Zero。 输入格式 两…...
Ostrakon-VL-8B实战:模拟互联网产品A/B测试中的视觉效果分析
Ostrakon-VL-8B实战:模拟互联网产品A/B测试中的视觉效果分析 每次产品迭代,设计团队和产品经理之间总少不了一场“拉锯战”。新版本的设计稿出来了,A方案简洁现代,B方案信息突出,到底哪个更能吸引用户点击?…...
Qwen3-14B多场景落地指南:内容创作、编程辅助、教育问答一体化方案
Qwen3-14B多场景落地指南:内容创作、编程辅助、教育问答一体化方案 1. 开箱即用的私有部署方案 Qwen3-14B私有部署镜像为企业和开发者提供了一站式解决方案,无需复杂的环境配置即可快速启用大模型能力。这个经过深度优化的镜像专为RTX 4090D 24GB显存环…...
30行代码,就是一个完整的AI Agent——Claude Code源码精读(一)
30行代码,就是一个完整的AI Agent——Claude Code源码精读(一) 核心摘要 大多数人谈起 Claude Code,想到的是"能写代码的 AI 助手"。但如果你看它的源码,会发现最核心的机制出奇地简单:一个 whil…...
ChatGPT_JCM深色模式实现:保护眼睛的界面显示方案
ChatGPT_JCM深色模式实现:保护眼睛的界面显示方案 【免费下载链接】ChatGPT_JCM 项目地址: https://gitcode.com/gh_mirrors/ch/ChatGPT_JCM ChatGPT_JCM是一款功能强大的AI交互工具,其深色模式实现为用户提供了舒适的夜间使用体验,有…...
NASM调试指南:如何高效定位和修复汇编错误
NASM调试指南:如何高效定位和修复汇编错误 【免费下载链接】nasm A cross-platform x86 assembler with an Intel-like syntax 项目地址: https://gitcode.com/gh_mirrors/na/nasm NASM(Netwide Assembler)作为一款跨平台的x86汇编器&…...
提升GitHub访问效率的实用方案
提升GitHub访问效率的实用方案 【免费下载链接】gh-proxy github release、archive以及项目文件的加速项目 项目地址: https://gitcode.com/gh_mirrors/gh/gh-proxy 诊断连接瓶颈 检测网络延迟指标 准备工作:确保系统已安装网络诊断工具(Linux默…...
Pixel Couplet Gen实操手册:微信小程序分包加载优化像素春联H5首屏速度
Pixel Couplet Gen实操手册:微信小程序分包加载优化像素春联H5首屏速度 1. 项目背景与核心价值 Pixel Couplet Gen是一款融合传统春节文化与现代像素艺术风格的创新应用。通过ModelScope大模型的文本生成能力,结合精心设计的8-bit视觉元素,…...
手把手教你用STM32F103C8T6+DHT11做个智能加湿器(附完整代码和PCB文件)
从零打造智能加湿器:STM32F103C8T6与DHT11的完美组合 在干燥的秋冬季节,一台能够自动调节湿度的智能加湿器不仅能提升生活舒适度,更是电子爱好者展示技能的绝佳项目。本文将带你从元器件选型开始,逐步完成一个基于STM32F103C8T6单…...
气电版通用自动分选机:圆柱电芯测试分选的精准之选
在新能源产业蓬勃发展的当下,圆柱电芯作为重要的储能元件,其生产过程中的质量把控至关重要。内阻和电压作为衡量电芯性能的关键指标,直接关系到电芯的使用寿命、充放电效率以及安全性。气电版通用自动分选机凭借其卓越的性能和精准的分选能力…...
