【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、算法思想
上文讲到算法的概念、复杂度,本文给大家介绍具体的算法思想,让大家对算法设计理念有个认识,后续再分别介绍各种算法。 算法思想 算法是解决问题的一种思想和方法,其基本思想是将一个复杂问题分解为多个简单的子问题,…...
高质量测试 Skill 编写手册 -- 渐进式披露
什么是渐进式披露渐进式披露是高质量 Skill 中最基础也最重要的技巧之一。 用一句话表达就是:不要把所有的规则和知识都一股脑的写在提示词中交给大模型,而是只在必要的时候,加载对应的知识。为什么需要渐进式披露在大模型领域有一句话叫上下…...
6款靠谱降AI率平台 改写实力出众
写论文时总担心AI生成痕迹太重影响成绩?别慌,这里整理了6款超实用的论文降AI率工具,堪称应对AI痕迹问题的"得力助手"。它们能有效识别并去除AI生成特征,改写能力出色,帮你轻松降低查重率,顺利通过…...
风暴崛起 Tempest Rising修改器2026官方正版最新版pc免费下载(看到请立即转存 资源随时失效)
下载链接 经典RTS重燃:Tempest Rising修改器核心机制与实战运用解析 在即时战略(RTS)游戏逐渐走向硬核与小众的当下,《Tempest Rising》(风暴崛起)以其致敬经典命令与征服(C&C)…...
保姆级教程:在Ubuntu 22.04上搞定rMATS 4.1.2安装,附赠conda环境配置与常见报错解决
从零搭建rMATS分析环境:Ubuntu 22.04实战指南与避坑手册当实验室新购置的Ubuntu服务器静静躺在角落,而导师那句"下周组会汇报可变剪切分析结果"还在耳边回响时,作为生物信息学新手的你,是否感到一阵恐慌?别担…...
为什么92%的DeepSeek微调失败?资深架构师拆解3类致命配置错误及实时诊断命令
更多请点击: https://kaifayun.com 第一章:DeepSeek模型微调失败率的行业现状与根本归因 近年来,DeepSeek系列大模型(如DeepSeek-V2、DeepSeek-Coder)在开源社区和企业私有化部署中广泛应用,但实证调研显示…...
诈骗分子利用微软内部账户发垃圾链接,微软能否解决安全漏洞?
诈骗事件曝光 几个月来,诈骗分子利用漏洞,从微软内部通常用于发送合法账户提醒的电子邮件地址发送垃圾邮件。目前不清楚他们如何利用系统,但能像新客户一样创建新微软账户,并以微软名义发邮件,易让人们误以为邮件真实。…...
【AI视频生成工具学习曲线深度报告】:20年AI工程经验总结的5大认知断层与30天速通路径
更多请点击: https://codechina.net 第一章:AI视频生成工具学习曲线的本质解构 AI视频生成工具的学习曲线并非线性陡峭的“技术门槛”,而是一组相互耦合的认知域跃迁过程——涵盖提示工程直觉、时序一致性理解、跨模态对齐敏感度以及算力-质…...
3分钟快速解锁:如何让你的索尼相机显示中文菜单?
3分钟快速解锁:如何让你的索尼相机显示中文菜单? 【免费下载链接】OpenMemories-Tweak Unlock your Sony cameras settings 项目地址: https://gitcode.com/gh_mirrors/op/OpenMemories-Tweak 还在为索尼相机只能显示英文或日文菜单而烦恼吗&…...
CleanMyWechat:你的微信磁盘空间救星,三步告别几十GB的缓存困扰
CleanMyWechat:你的微信磁盘空间救星,三步告别几十GB的缓存困扰 【免费下载链接】CleanMyWechat 自动删除 PC 端微信缓存数据,包括从所有聊天中自动下载的大量文件、视频、图片等数据内容,解放你的空间。 项目地址: https://git…...
桌面实时股票监控终极指南:5分钟打造你的Windows投资助手
桌面实时股票监控终极指南:5分钟打造你的Windows投资助手 【免费下载链接】TrafficMonitorPlugins 用于TrafficMonitor的插件 项目地址: https://gitcode.com/gh_mirrors/tr/TrafficMonitorPlugins 在当今快节奏的数字时代,投资者们常常需要在工作…...
