多线程(三)
上一期关于线程的执行,咱们说到线程是 “ 随机调度,抢占式执行 ”。所以我们对于线程之间执行的先后顺序是难以预知的。
例如咱们打篮球的时候,球场上的每一位运动员都是一个独立的 “ 执行流 ”,也可以认为是一个线程,进球就是咱们要执行的 “ 任务 ”,我们打球肯定不是说每个球员都想着抢球投球,要想赢得一场漂亮的比赛,咱们肯定是要执行战术的,每个人都有自己的位置,什么时候谁持球做什么,这都是很严谨的。只有多位运动员相互配合,按照一定顺序打出进攻防守,这样才能赢球。
线程是 “ 天生 ” 就这样互相抢占式执行的,但是我们难道就放任线程之间这样子随意执行不管嘛,当然不是了,有些时候在特定的场景下,咱们对实现线程的调度执行是有一定要求的。而这就引入了我们的 wait(等待) 和 notify(通知)。
(1)wait()/ wait(long timeout):让当前线程进入等待状态。
(2)notify()/ notifyAll():唤醒在当前对象上等待的线程 / 唤醒全部线程。
注意:wait 和 notify 、notifyAll 都是 Object 类的方法。
一 . wait(等待)
wait 要做的事:
(1)使当前执行代码的线程进行等待(将线程放到等待队列中)。
(2)释放当前的锁。
(3)满足一定条件时被唤醒,重新尝试获取这个锁。
注意:wait 一定要搭配 synchornized 使用,不然会直接抛出异常。
wait 结束等待的条件:
(1)其他线程调用该对象的 notify 方法。
(2)当使用 wait 的带参数版本时,等待超时自动唤醒。
(3)其他线程调用该线程的 interrupted 方法,会导致 wait 抛出 InterruptedException 异常。
咱们通过代码来看一下:
大家可以看出来,当我们使用无参数版本的 wait 时,若是我们不将其唤醒,那么这个线程就会一直等待下去,直到被唤醒为止。
wait 默认是 “死等 ”, 这里我们再使用 wait 的带参数版本,看一下是否会自动唤醒 wait 。
如图所示,经过咱们等待前后的时间差可以看出 wait 确实是等待了 3000 ms 还没有等待人来唤醒它,这时候它就不等了,线程直接继续执行。
二 . notify(通知)
notify 要做的事:
(1)唤醒 wait 等待的线程。
(2)如果有多个线程等待,则由线程调度器随机唤醒其中的一个呈 wait 状态的线程。
(3)notify 同样要配合 synchornized 使用。
(4)在 notify()方法之后,当前线程不会立马释放该对象锁,而是要等待执行 notify()方法的线程将程序执行完,也就是退出同步代码块后才会释放对象锁。
大家通过下列代码看一下,wait 和 notify 配合 synchornized 使用:
notifyAll 跟 notify 的区别就在于:
(1)notify 是随机唤醒等待队列中的一个线程,其余还有的线程还得乖乖等着。那么我们还想要继续唤醒剩下的线程怎么办呢?这个时候有小伙伴就灵机一动了,我们多唤醒几次,多调用几次 notify 不就行了吗?NONONO,这样可不行,要想唤醒剩下的线程,我们得在各线程内部进行 wait 和 notify 的配合使用才行。
接下来我们来看这样一个示例,按照顺序打印 A、B、C :
在这里再一次强调,我们线程的执行是 “ 随机调度,抢占式执行 ”,所以这里打印A、B、C的顺序我们是无法预知的,如下图所示。
这个时候咱们就需要 wait 和 notify 配合使用,并且我们需要两把锁。
此时我们不管经过多少次试验,结果都是我们预期的 A、B、C 顺序。
注意:这里我们在线程 t1 中为什么要强制等待一个 10 ms 呢?如果我们不加这个强制等待就会发现,当我们执行代码的时候,只能打印出 A ,然后程序就不动了。这是为什么呢?这是因为大概率存在这样的情况:我们的 t1 先执行了打印和 notify ,执行的很快,然后我们的 t2 才执行 wait ,这就意味着 t1 的通知过早了,这样就会造成我们的 t2 一直等下去,因为属于它的通知已经错过了。
这就好比如一个悲伤的故事,在学生时代,有一对男孩女孩互生情愫,但都是暗恋,等到即将毕业前,女孩在送给男孩的一本书里偷偷夹了一封信,已示告白,但是粗心大意的男生并没有发现,直到多年后,男孩偶然间翻开这本书,这才发现这封已经泛黄的告白信,但此刻时光荏苒,物是人非事事休咯,这就是错失的遗憾。
这个故事是我在听老师讲课的时候,老师举的例子,但是很不幸的是,我也有着一段这样的经历,不是百分百一样,但也所差无几。
缘分就像一本书,翻得太快会错过,读的认真又流泪。所以各位,有时候冲动一点不是坏事,大家在该勇敢的时候还是要牢牢地抓出那个他 / 她,忘诸君不留遗憾。
(2)notifyAll 是一下将所有等待队列中的线程全部唤醒,但是,这些锁会重新竞争。notifyAll 很简单,咱们就不在这儿演示了。
三 . wait 和 sleep 的区别
理论上来说,wait 和 sleep 是没有任何可比性的,因为这两个概念虽然实现的作用大致相同,都可以让线程放弃执行一段时间,但是并不是一个性质的。
(1)wait 是用于线程之间通信的,sleep 是让线程阻塞一段时间。
(2)wait 需要搭配 synchornized 使用,sleep 不需要,直接通过 Thread 调用即可。
(3)wait 是 Object 的方法,sleep 是 Thread 的静态方法。
(4)sleep 与锁无关,不加锁,sleep 可以正常使用;加了锁,sleep 操作,不会释放锁,相当于在 sleep “ 休眠 ” 的这段时间内,它就是抱着锁睡得,那么其余线程都拿不到锁。
OKK,今天就说这么多了,这一期是专门讲解 wait 和 notify 的,大概就这些了。咱们下期再见吧,与诸君共勉!!!
相关文章:
多线程(三)
上一期关于线程的执行,咱们说到线程是 “ 随机调度,抢占式执行 ”。所以我们对于线程之间执行的先后顺序是难以预知的。 例如咱们打篮球的时候,球场上的每一位运动员都是一个独立的 “ 执行流 ”,也可以认为是一个线程࿰…...
微服务商城(1)开篇、服务划分
参考:https://mp.weixin.qq.com/s?__bizMzg2ODU1MTI0OA&mid2247485597&idx1&sn7e85894b7847cc50df51d66092792453&scene21#wechat_redirect 为什么选择go-zero go-zero 为我们提供了许多高并发场景下的实用工具,比如为了降低接口耗时…...
刘强东 “猪猪侠” 营销:重构创始人IP的符号革命|创客匠人热点评述
当刘强东身着印有外卖箱猪猪侠的 T 恤漫步东京涩谷街头时,这场看似荒诞的行为艺术实则揭开了互联网商业竞争的新篇章。这位曾经以严肃企业家形象示人的京东创始人,正通过二次元 IP 的深度绑定,完成从商业领袖到文化符号的华丽转身。 一、IP …...
MQ消息队列的深入研究
目录 1、Apache Kafka 1.1、 kafka架构设 1.2、最大特点 1.3、功能介绍 1.4、Broker数据共享 1.5、数据一致性 2、RabbitMQ 2.1、架构图 2.2、最大特点 2.3、工作原理 2.4、功能介绍 3、RocketMQ 3.1、 架构设计 3.2、工作原理 3.3、最大特点 3.4、功能介绍 3…...
填涂颜色(bfs)
归纳编程学习的感悟, 记录奋斗路上的点滴, 希望能帮到一样刻苦的你! 如有不足欢迎指正! 共同学习交流! 🌎欢迎各位→点赞 👍+ 收藏⭐ + 留言📝 含泪播种的人一定能含笑收获! 题目描述 由数字 0 0 0 组成的方阵中,有一任意形状的由数字 1 1 1 构成的闭合圈。现…...
FFplay 音视频同步机制解析:以音频为基准的时间校准与动态帧调整策略
1.⾳视频同步基础 1.2 简介 看视频时,要是声音和画面不同步,体验会大打折扣。之所以会出现这种情况,和音视频数据的处理过程密切相关。音频和视频的输出不在同一个线程,就像两个工人在不同车间工作,而且不一定会同时…...
【Linux笔记】——进程信号的捕捉——从中断聊聊OS是怎么“活起来”的
🔥个人主页🔥:孤寂大仙V 🌈收录专栏🌈:Linux 🌹往期回顾🌹:【Linux笔记】——进程信号的保存 🔖流水不争,争的是滔滔不息 一、信号捕捉的流程二、…...
VCS X-PROP建模以及在方针中的应用
VCS X-PROP建模以及在方针中的应用 摘要:VCS X-Prop(X-Propagation)是 Synopsys VCS 仿真工具中的一种高级功能,用于增强 X 态(未知态)和 Z 态(高阻态)在 RTL 仿真中的建模和传播能力…...
OpenSHMEM 介绍和使用指南
OpenSHMEM 介绍和使用指南 什么是 OpenSHMEM? OpenSHMEM 是一个用于并行计算的标准化 API,它提供了一种分区全局地址空间 (PGAS) 编程模型。OpenSHMEM 最初由 Cray 公司开发,后来成为一个开源项目,旨在为高性能计算提供高效的通…...
Electron入门指南:用前端技术打造桌面应用
🌟 目录速览 什么是Electron?为什么要用Electron?核心概念三分钟掌握快速创建第一个应用典型应用场景开发注意事项常见问题解答 一、什么是Electron?🤔 Electron就像魔法转换器,它能将你熟悉的࿱…...
机器学习第十讲:异常值检测 → 发现身高填3米的不合理数据
机器学习第十讲:异常值检测 → 发现身高填3米的不合理数据 资料取自《零基础学机器学习》。 查看总目录:学习大纲 关于DeepSeek本地部署指南可以看下我之前写的文章:DeepSeek R1本地与线上满血版部署:超详细手把手指南 一、幼儿…...
【Redis】缓存穿透、缓存雪崩、缓存击穿
1.缓存穿透 是指客户端请求的数据在缓存中和数据库中都不存在,这样缓存永远不会生效,导致请求直接穿透缓存到达数据库,给数据库带来压力的情况。 常见的解决方案有两种: 缓存空对象:实现简单,维护方便&am…...
科学养生指南:打造健康生活
在快节奏的现代生活中,健康养生成为人们关注的焦点。科学养生无需复杂理论,掌握以下几个关键要素,就能为身体构筑坚实的健康防线。 合理饮食是健康的基础。世界卫生组织建议,每天应摄入至少 5 份蔬菜和水果,保证维生…...
解锁健康生活:现代养生实用方案
早上被闹钟惊醒后匆忙灌下咖啡,中午用外卖应付一餐,深夜刷着手机迟迟不肯入睡 —— 这样的生活模式,正在不知不觉侵蚀我们的健康。科学养生并非遥不可及的目标,只需从生活细节入手,就能逐步改善身体状态。 饮食管理…...
深入解析JVM字节码解释器执行流程(OpenJDK 17源码实现)
一、核心流程概述 JVM解释器的核心任务是将Java字节码逐条翻译为本地机器指令并执行。其执行流程可分为以下关键阶段: 方法调用入口构建:生成栈帧、处理参数、同步锁等。 字节码分派(Dispatch):根据字节码跳转到对应…...
【HCIA】BFD
前言 前面我们介绍了浮动路由以及出口路由器的默认路由配置,可如此配置会存在隐患,就是出口路由器直连的网络设备并不是运营商的路由器,而是交换机。此时我们就需要感知路由器的存活状态,这就需要用到 BFD(Bidirectio…...
vue使用路由技术实现登录成功后跳转到首页
文章目录 一、概述二、使用步骤安装vue-router在src/router/index.js中创建路由器,并导出在vue应用实例中使用router声明router-view标签,展示组件内容 三、配置登录成功后跳转首页四、参考资料 一、概述 路由,决定从起点到终点的路径的进程…...
用户模块 - IP归属地框架吞吐测试
一、引言 在很多用户系统中,我们常常需要知道一个IP地址来自哪里,比如判断一个用户是否来自国内、识别异常登录等。而实现这个功能,通常会使用一个“IP归属地解析框架”,它可以根据IP地址返回国家、省份、城市等信息。 不过&#…...
生活实用小工具-手机号归属地查询
一、接口定义 手机号码归属地接口(又称手机号查询API)是一种通过输入手机号码,快速返回其归属地信息(如省份、城市、运营商、区号等)的应用程序接口。其数据基础来源于运营商(移动、联通、电信)…...
鸿蒙-5.1.0-release源码下载
源码获取 前提条件 注册码云gitee帐号。注册码云SSH公钥,请参考码云帮助中心。安装git客户端和git-lfs并配置用户信息。 git config --global user.name "yourname" # 这得和gitee的账号对的上 git config --global user.email "your-email-ad…...
2020年下半年试题三:论云原生架构及其应用
论文库链接:系统架构设计师论文 论文题目 近年来,随着数字化转型不断深入,科技创新与业务发展不断融合,各行各业正在从大工业时代的固化范式进化成面向创新型组织与灵活型业务的崭新模式。在这一背景下,以容器盒微服务…...
Flutter到HarmonyOS Next 的跨越:memory_info库的鸿蒙适配之旅
Flutter到鸿蒙的跨越:memory_info库的鸿蒙适配之旅 本项目作者:kirk/坚果 您可以使用这个Flutter插件来更改应用程序图标上的角标 作者仓库:https://github.com/MrOlolo/memory_info/tree/master/memory_info 在数字化浪潮的推动下&#…...
昆士兰科技大学无人机自主导航探索新框架!UAVNav:GNSS拒止与视觉受限环境中的无人机导航与目标检测
作者: Sebastien Boiteau, Fernando Vanegas, Felipe Gonzalez 单位:昆士兰科技大学电气工程与机器人学院,昆士兰科技大学机器人中心 论文标题:Framework for Autonomous UAV Navigation and Target Detection in Global-Naviga…...
uniapp设置 overflow:auto;右边不显示滚动条的问题
设置了overflow:auto;或者其它overflow的属性不显示滚动条是因为在uniapp中默认隐藏了滚动条 解决方法: //强制显示滚动条 ::-webkit-scrollbar {width: 8px !important;background: #ccc !important;display: block !important;}//设置滚动条颜色.cu-…...
基于SIP协议的VOIP话机认证注册流程分析与抓包验证
话机的认证注册报文怎么看? 在SIP协议中,当VOIP话机首次启动的时候,他会向SIP服务器发送一个Register请求来注册自己的信息地址,,告诉服务器 话机当前在线话机的IP地址和端口是什么话机希望接收通话的联系方式 认证注…...
JS,ES,TS三者什么区别
Java Script(JS)、ECMAScript(ES)、TypeScript(TS) 的核心区别与关联的详细解析,结合技术背景、设计目标及应用场景展开说明: 一、核心定义与关系 JavaScript(JS) 定义:一种动态类型、基于原型的脚本语言,由 Netscape 公司于 1995 年首次开发,用于网页交互功能。角…...
深度理解指针(2)
🎁个人主页:工藤新一 🔍系列专栏:C面向对象(类和对象篇) 🌟心中的天空之城,终会照亮我前方的路 🎉欢迎大家点赞👍评论📝收藏⭐文章 深入理解指…...
笔记本/台式机加装PCIe 5.0固态硬盘兼容性与安装方法详解 —— 金士顿Kingston FURY Renegade G5装机指南
在2025年,存储设备市场迎来了革命性的升级浪潮。作为最高性能PCIe 5.0固态硬盘的代表,Kingston FURY Renegade G5 PCIe 5.0 NVMe M.2 固态硬盘不仅刷新了读写速度新高,更以优异的能耗和温控表现成为高端PC、游戏本和工作站升级的“定心丸”。…...
使用libUSB-win32的简单读写例程参考
USB上位机程序的编写,函数的调用过程. 调用 void usb_init(void); 进行初始化 调用usb_find_busses、usb_find_devices和usb_get_busses这三个函数,获得已找到的USB总线序列;然后通过链表遍历所有的USB设备,根据已知的要打开USB设…...
Tailwind CSS 实战教程:从入门到精通
Tailwind CSS 实战教程:从入门到精通 前言 在Web开发的世界里,CSS框架层出不穷。从早期的Bootstrap到现在的Tailwind CSS,前端开发者们总是在寻找更高效、更灵活的样式解决方案。今天,我们就来深入探讨这个被称为"实用优先…...
【IC】如何获取良好的翻转数据来改进dynamic IR drop分析?
动态电压降分析是一个复杂的过程。为了成功执行适当的分析,需要组合多个输入文件和不同的配置设置。 切换场景是任何动态压降分析的关键。设计中的所有门电路和实例不会同时处于活动状态。此外,对于更复杂的单元,可能的切换模式会非常多。这…...
WebGL知识框架
一、WebGL 基础概念 1. WebGL 简介 是什么? 基于 OpenGL ES 的浏览器 3D 图形 API,直接操作 GPU 渲染。 核心特点 底层、高性能、需手动控制渲染管线。 依赖 JavaScript 和 GLSL(着色器语言)。 与 Three.js 的关系 Three.js…...
集成 ONLYOFFICE 与 AI 插件,为您的服务带来智能文档编辑器
在数字化办公浪潮中,文档处理效率对企业发展具有关键意义。但许多办公平台仅支持基础流程,查阅、批注和修改需借助外部工具,增加了操作复杂性和沟通成本。本文将为开发者介绍如何集成 ONLYOFFICE 文档并利用其中的 AI 插件,智能处…...
Simulink模型回调
Simulink 模型回调函数是一种特殊的 MATLAB 函数,可在模型生命周期的特定阶段自动执行。它们允许用户自定义模型行为、执行初始化任务、验证参数或记录数据。以下是各回调函数的详细说明: 1. PreLoadFcn 触发时机:Simulink 模型加载到内存之…...
网络协议分析 实验五 UDP-IPv6-DNS
文章目录 实验5.1 UDP(User Datagram Protocol)练习二 UDP单播通信练习三 利用仿真编辑器编辑UDP数据包,利用工具接收练习四 UDP受限广播通信练习六 利用仿真编辑器编辑IPV6的UDP数据包并发送实验5.2 DNS(Domain Name System)练习二 仿真编辑DNS查询报文(…...
共享代理IP vs 动态IP:企业级业务场景的选型深度解析
在数字化转型加速的今天,IP地址管理已成为企业网络架构中的核心命题。无论是跨境电商的多账号运营、大数据采集的精准度保障,还是网络安全的纵深防御,IP解决方案的选择直接关系到业务效能与合规风险。本文将从技术底层逻辑出发,结…...
鸿蒙OSUniApp制作一个小巧的图片浏览器#三方框架 #Uniapp
利用UniApp制作一个小巧的图片浏览器 最近接了个需求,要求做一个轻量级的图片浏览工具,考虑到多端适配的问题,果断选择了UniApp作为开发框架。本文记录了我从0到1的开发过程,希望能给有类似需求的小伙伴一些参考。 前言 移动互联…...
Java并发编程面试题:并发工具类(10题)
🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,精通Java编…...
【Oracle专栏】扩容导致数据文件 dbf 丢失,实操
Oracle相关文档,希望互相学习,共同进步 风123456789~-CSDN博客 1.背景 同事检查扩容情况,发现客户扩容后数据盘后,盘中原有文件丢失,再检查发现数据库没有启动。通过检查发现数据盘中丢失的是oracle的 dbf 表空间文件。数据库无法启动。 检查情况:1)没有rman备份 …...
【Linux】Linux 的管道与重定向的理解
目录 一、了解Linux目录配置标准FHS 二、Linux数据重定向的理解与操作 2.1基本背景 2.2重定向的理解 2.3Linux管道命令的理解与操作 三、Linux 环境变量与PATH 3.1环境变量PATH 一、了解Linux目录配置标准FHS FHS本质:是一套规定Linux目录结构,软…...
【交互 / 差分约束】
题目 代码 #include <bits/stdc.h> using namespace std; using ll long long;const int N 10510; const int M 200 * 500 10; int h[N], ne[M], e[M], w[M], idx; ll d[N]; int n, m; bool st[N]; int cnt[N];void add(int a, int b, int c) {w[idx] c, e[idx] b…...
1. Go 语言环境安装
👑 博主简介:高级开发工程师 👣 出没地点:北京 💊 人生目标:自由 ——————————————————————————————————————————— 版权声明:本文为原创文章…...
灰度图像和RGB图像在数据大小和编码处理方式差别
技术背景 好多开发者对灰度图像和RGB图像有些认知差异,今天我们大概介绍下二者差别。灰度图像(Grayscale Image)和RGB图像在编码处理时,数据大小和处理方式的差别主要体现在以下几个方面: 1. 通道数差异 图像类型通道…...
Lord Of The Root: 1.0.1通关
Lord Of The Root: 1.0.1 来自 <Lord Of The Root: 1.0.1 ~ VulnHub> 1,将两台虚拟机网络连接都改为NAT模式 2,攻击机上做namp局域网扫描发现靶机 nmap -sn 192.168.23.0/24 那么攻击机IP为192.168.23.182,靶场IP192.168.23.247 3&…...
虚拟机安装CentOS7网络问题
虚拟机安装CentOS7网络问题 1. 存在的问题1.1 CentOS7详细信息 2. 解决问题3.Windows下配置桥接模式 1. 存在的问题 虽然已经成功在虚拟机上安装了CentOS7,但是依旧不能上网。 1.1 CentOS7详细信息 [fanzhencentos01 ~]$ hostnamectlStatic hostname: centos01Ic…...
AI-02a5a6.神经网络-与学习相关的技巧-批量归一化
批量归一化 Batch Normalization 设置合适的权重初始值,则各层的激活值分布会有适当的广度,从而可以顺利的进行学习。那么,更进一步,强制性的调整激活值的分布,是的各层拥有适当的广度呢?批量归一化&#…...
matlab实现蚁群算法解决公交车路径规划问题
使用蚁群算法解决公交车路径规划问题的MATLAB代码实现,包含详细注释和仿真流程。该算法以站点间行驶时间或距离为优化目标,寻找最优公交路线。 1. 问题建模与参数设置 1.1 输入数据 站点坐标:假设有20个公交站点,随机生成位置。…...
Agent Builder API - Agent Smith 扩展的后端服务(开源代码)
一、软件介绍 文末提供程序和源码下载 Agent Builder API - Agent Smith 扩展的后端服务(开源代码)手动设置:在本地计算机中克隆此存储库并启动 python FAST API 服务器。(可选)安装并设置 Mongo DB。Dev Container…...
C++类和对象之相关特性
C 一.类型转换隐式类型转换 二.static成员一、static成员变量二、static成员函数三、static成员的存储位置四、总结 三.友元一、友元函数二、友元类三、友元成员函数四、总结 四.内部类五.匿名对象六.new 一.类型转换 在C中,类类型转换是指将一个类的对象转换为另一…...
容器编排的革命:Kubernetes如何引领IT的云原生时代
文章目录 Kubernetes的本质:容器世界的智能指挥家Kubernetes的核心功能包括: Kubernetes的演进:从谷歌的实验到全球标准核心技术:Kubernetes的基石与生态1. Pod与容器:最小调度单位2. Deployment:无状态应用…...