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

等待和通知

引入

由于线程是抢占式执行的,因此线程之间的执行的先后顺序难以预知

但是实际开发中我们希望合理协调多个线程之间执行的先后顺序.

这里的干预线程先后顺序,并不是影响系统的调度策略(内核里调度线程,仍然是无序调度).

就是相当于在应用程序代码中,让后执行的线程主动放弃被调度的机会.就可以让执行线程,先把对应的代码执行完了.

完成这个协调工作,主要涉及到三个方法

wait()/wait(long timeout):让当前线程进入准备状态.

notify()/notifyAll():唤醒在当前对象上等待的线程.

注意:wait,notify,notifyAll都是Object类的方法.

wait()方法

一个线程重复拿到锁,别的线程无法拿到锁,这个情况称为"线程饿死/饥饿".属于概率性事件.虽然不像死锁那样严重.这种情况确实是bug.没那么严重,但也极大地影响了程序的运行.

处理:使该线程主动放弃对锁的争夺/放弃去cpu调度执行(进入阻塞,也就是wait).一直到这个条件具备,再解除阻塞,参与锁竞争.

wait做的事情:

1.使当前执行代码的线程进行等待.(把线程放到等待队列中).

2.释放当前的锁.

3.满足一定条件时被唤醒,重新尝试获取这个锁.

其中,1,2条可以让其他线程有机会拿到锁了.第三条指当其它线程调用notify的时候,wait解除阻塞.

wait结束等待的条件:

1.其它线程调用该对象的notify方法.

2.wait等待时间超时(wait方法提供一个带有timeout参数的版本,来指定等待时间)->这是为了防止死等,具有鲁棒性

3.其它线程调度该等待线程的interrupted方法,导致wait抛出InterruptException异常.

观察wait()方法的使用:

public static void main(String[] args) throws InterruptedException {Object locker = new Object();synchronized (object) {System.out.println("等待中");object.wait();System.out.println("等待结束");}
}

这样执行到object.wait()之后就会一直等待下去,那么程序肯定不能这样一直等待下去了.这个时候就需要使用到了另外一个方法以唤醒,也就是notify().

notify方法

notify方法是唤醒等待的线程.

 1.方法notify()也要在同步方法或同步块中调用,该方法是用来通知那些可能等待该对象的对象锁的其它线程,对其发出通知notify,并使它们重新获取该对象的对象锁.

2.如果有多个线程等待,则有线程调度器随机挑选出一个呈wait状态的线程.(前提是操作的是同一个锁).并没有"先来后到"

3.在notify()方法后,当前线程不会马上释放该对象锁,要等到执行notify()方法的线程将程序执行完,也就是退出同步代码块之后才会释放对象锁.

代码示例:

public class ThreadTest5 {public static Object locker = new Object();public static void main(String[] args) {Thread t1 = new Thread(() -> {synchronized (locker) {System.out.println("t1 wait 之前");try {//t1执行起来之后,执行到这,就会先立即释放锁,进入wait方法(释放锁+阻塞等待)locker.wait();System.out.println("t1 wait 之后");} catch (InterruptedException e) {e.printStackTrace();}}});Thread t2 = new Thread(() -> {try {//t2执行起来之后,先进行sleep(3000)(这个sleep操作就可以让t1先拿到锁)//如果先notify虽然不会有副作用(不会出现异常之类的),但是wait就无法被唤醒,逻辑上有问题Thread.sleep(3000);//t2sleep结束之后,由于t1是wait状态,t2就能拿到锁//接下来打印t2notify之前,执行notify操作,这个操作就能唤醒t1(此时t1就从WAITING状态恢复过来了)synchronized (locker) {System.out.println("t2 notify 之前");locker.notify();//但是由于t2此时还没有释放锁,WAITING恢复之后,尝试获取锁,就可能出现一个小小的阻塞,这个阻塞是由锁竞争引起的//t1目前处于BLOCKED状态,但是时间比较短,肉眼看不见System.out.println("t2 notify 之后");}//t2释放锁之后,就可以继续执行t1} catch (InterruptedException e) {e.printStackTrace();}});t1.start();t2.start();}
}

notifyAll()方法

notify方法只是唤醒某一个等待线程.使用notifyAll方法可以一次唤醒所有的等待线程.

但是注意,这些线程在wait返回时,要重新获取锁,就会因为锁的竞争,使这些线程实际上是一个一个串行执行的(谁先谁后拿到锁是不一定的). 

 理解notify和notifyAll

notify只唤醒等待队列中的一个线程.其它线程还是乖乖等着

notifyAll一下全都唤醒,需要这些线程重新竞争锁.

相比之下,还是更倾向于notify.因为notifyAll全部唤醒之后,不好控制

 wait和sleep的对比

其实理论上wait和sleep完全是没有可比性的,因为一个是用于线程之间通信的,一个是让线程阻塞一段时间,唯一的共同的就是都可以让线程放弃执行一段时间.

1.wait可通过notify唤醒,sleep通过Interrupt唤醒

2.使用wait的最主要的目标,一是不知道夺少时间的前提下使用的.所谓的"超时间",就是"兜底"

使用sleep,一定是直到多少时间的前提下使用的,这个操作不因该作为正常业务逻辑(通过异常唤醒,说明程序应该是出现特殊情况了)

3.wait搭配synchronized使用,sleep不需要

4.wait是Object的方法,sleep是Thread的静态方法

相关文章:

等待和通知

引入 由于线程是抢占式执行的,因此线程之间的执行的先后顺序难以预知 但是实际开发中我们希望合理协调多个线程之间执行的先后顺序. 这里的干预线程先后顺序,并不是影响系统的调度策略(内核里调度线程,仍然是无序调度). 就是相当于在应用程序代码中,让后执行的线程主动放弃被…...

vscode 如何将正则匹配到的字符前批量加字符

最近想用vscode将正则匹配到的东西签名批量https,替换时可以用$1来替换正则匹配到的字符串,如下所示...

上个月暴涨34.6%后,SoundHound AI股票现在还能买入吗?

来源:猛兽财经 作者:猛兽财经 揭开SoundHound AI股价波动的原因 S&P Global Market Intelligence的数据显示,在摆脱了10月份的大幅下跌后,SoundHound AI的股价在11月份实现了34.6%的涨幅。 原因是该公司公布了稳健的第三季…...

Termux+Hexo结合内网穿透轻松实现安卓手机搭建博客网站发布公网访问

文章目录 前言 1.安装 Hexo2.安装cpolar3.远程访问4.固定公网地址 前言 Hexo 是一个用 Nodejs 编写的快速、简洁且高效的博客框架。Hexo 使用 Markdown 解析文章,在几秒内,即可利用靓丽的主题生成静态网页。 下面介绍在Termux中安装个人hexo博客并结合…...

程序员的养生指南(生命诚可贵,一人永流传!珍惜生命,从你我做起)

作为程序员,我们经常需要长时间坐在电脑前工作,这对我们的身体健康造成了很大的影响。为了保持健康,我们需要采取一些养生措施来延寿。下面是我个人的一些养生经验和建议,希望能对大家有所帮助。 1、合理安排工作时间:…...

FP独立站怎么搭建?看这一篇就够了!强烈建议收藏!

在2023疫情结束年,商家为了在跨境电商市场上获取更多的份额,FP建站需求大军席卷而来,越来越多的创业者和企业开始涉足跨境电商独立站领域,尤其是FP独立站,FP商家想要通过FP独立站、FP广告投放,FP支付&#…...

【华为OD题库-068】找出经过特定点的路径长度-java

题目 输入一个字符串,都是以大写字母组成,每个相邻的距离是1,第二行输入一个字符串,表示必过的点。 说明 每个点可过多次。求解经过这些必过点的最小距离是多少? 示例1 输入输出示例仅供调试,后台判题数据一般不包含示…...

高性能队列框架-Disruptor使用、Netty结合Disruptor大幅提高数据处理性能

高性能队列框架-Disruptor 首先介绍一下 Disruptor 框架,Disruptor是一个通用解决方案,用于解决并发编程中的难题(低延迟与高吞吐量),Disruptor 在高并发场景下性能表现很好,如果有这方面需要,…...

Linux学习笔记3 xshell(lnmp)

xshell能连接虚拟机的前提是真机能够ping通虚拟机网址 装OpenSSL依赖文件 [rootlocalhost nginx-1.12.2]# yum -y install openssl pcre-devel 依赖检测[rootlocalhost nginx-1.12.2]# ./configure [rootlocalhost nginx-1.12.2]# yum -y install zlib [rootlocalhost n…...

分享几个可以免费使用GPT工具

1. 国产可以使用GPT3.5和4.0的网站,每日有免费的使用额度,响应速度,注册时不用使用手机号,等个人信息,注重用户隐私,好评! 一个好用的ChatGPT系统 ,可以免费使用3.5 和 4.0https://…...

一篇文章带你快速入门 Nuxt.js 服务端渲染

1. Nuxt.js 概述 1.1 我们一起做过的SPA SPA(single page web application)单页 Web 应用,Web 不再是一张张页面,而是一个整体的应用,一个由路由系统、数据系统、页面(组件)系统等等&#xff0…...

导入JDBC元数据到Apache Atlas

前言 前期实现了导入MySQL元数据到Apache Atlas, 由于是初步版本,且功能参照Atlas Hive Hook,实现的不够完美 本期对功能进行改进,实现了导入多种关系型数据库元数据到Apache Atlas 数据库schema与catalog 按照SQL标准的解释,…...

大数据项目——基于Django/协同过滤算法的房源可视化分析推荐系统的设计与实现

大数据项目——基于Django/协同过滤算法的房源可视化分析推荐系统的设计与实现 技术栈:大数据爬虫/机器学习学习算法/数据分析与挖掘/大数据可视化/Django框架/Mysql数据库 本项目基于 Django框架开发的房屋可视化分析推荐系统。这个系统结合了大数据爬虫、机器学…...

[网鼎杯 2020 朱雀组]phpweb1

提示 call_user_func()函数先通过php内置函数来进行代码审计绕过system(##不止一种方法) 拿到题目养成一个好的习惯先抓个包 从抓到的包以及它首页的报错来看,这里死活会post传输两个参数func以及p func传输函数,而p则是传输参数的…...

深度学习之注意力机制

注意力机制与外部记忆 注意力机制与记忆增强网络是相辅相成的,神经网络去从内存中或者外部记忆中选出与当前输入相关的内容时需要注意力机制,而在注意力机制的很多应用场景中,我们的外部信息也可以看作是一个外部的记忆 这是一个阅读理解任务…...

WordPress:解决xmlrpc.php被扫描爆破的风险

使用WordPress的朋友都知道,一些【垃圾渣渣】会利用xmlrpc.php文件来进行攻击,绕过WP后台错误登录次数限制进行爆破。虽然密码复杂的极难爆破,但及其占用服务器资源。 方法一、利用宝塔防火墙(收费版) 一般可以直接使…...

Fiddler抓包模拟器(雷电模拟器)

Fiddler设置 List item 打开fiddler,的options 点击OK,重启fiddler 模拟器 更改网络设置 IP可以在电脑上终端上查看 然后在模拟器浏览器中输入IP:端口 安装证书...

RepidJson将内容写入文件

使用 RapidJSON 将内容写入文件的步骤如下: 创建一个 rapidjson::Document 对象,将需要写入文件的内容存储到其中。创建一个 rapidjson::StringBuffer 对象来保存 JSON 字符串。将 rapidjson::Document 对象转换为 JSON 字符串,并将其放入 r…...

Endnote使用教程

原由 最近要进行开题报告,要求不低于60文献的阅读与引用,单独插入引入我觉得是非常繁琐的事情,所以就借助Endnote这个工具,减少我们的工作量。 使用方法 第一步:先新建一个数据库,这样子可以在这个数据库…...

java中用Thead创建线程和用Runnable创建线程的区别是什么?

在 Java 中,创建线程的两种主要方式是通过继承 Thread 类和通过实现 Runnable 接口。下面是它们之间的主要区别: 1. 继承 Thread 类: class MyThread extends Thread {public void run() {// 线程执行的代码} }// 创建并启动线程 MyThread …...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止

<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet&#xff1a; https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

条件运算符

C中的三目运算符&#xff08;也称条件运算符&#xff0c;英文&#xff1a;ternary operator&#xff09;是一种简洁的条件选择语句&#xff0c;语法如下&#xff1a; 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true&#xff0c;则整个表达式的结果为“表达式1”…...

MySQL中【正则表达式】用法

MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现&#xff08;两者等价&#xff09;&#xff0c;用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例&#xff1a; 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中&#xff0c;电磁频谱已成为继陆、海、空、天之后的 “第五维战场”&#xff0c;雷达作为电磁频谱领域的关键装备&#xff0c;其干扰与抗干扰能力的较量&#xff0c;直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器&#xff0c;凭借数字射…...

代码随想录刷题day30

1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币&#xff0c;另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额&#xff0c;返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】&#xff0c;分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...

Oracle11g安装包

Oracle 11g安装包 适用于windows系统&#xff0c;64位 下载路径 oracle 11g 安装包...

FOPLP vs CoWoS

以下是 FOPLP&#xff08;Fan-out panel-level packaging 扇出型面板级封装&#xff09;与 CoWoS&#xff08;Chip on Wafer on Substrate&#xff09;两种先进封装技术的详细对比分析&#xff0c;涵盖技术原理、性能、成本、应用场景及市场趋势等维度&#xff1a; 一、技术原…...

【版本控制】GitHub Desktop 入门教程与开源协作全流程解析

目录 0 引言1 GitHub Desktop 入门教程1.1 安装与基础配置1.2 核心功能使用指南仓库管理日常开发流程分支管理 2 GitHub 开源协作流程详解2.1 Fork & Pull Request 模型2.2 完整协作流程步骤步骤 1: Fork&#xff08;创建个人副本&#xff09;步骤 2: Clone&#xff08;克隆…...

21-Oracle 23 ai-Automatic SQL Plan Management(SPM)

小伙伴们&#xff0c;有没有迁移数据库完毕后或是突然某一天在同一个实例上同样的SQL&#xff0c; 性能不一样了、业务反馈卡顿、业务超时等各种匪夷所思的现状。 于是SPM定位开始&#xff0c;OCM考试中SPM必考。 其他的AWR、ASH、SQLHC、SQLT、SQL profile等换作下一个话题…...