Java EE之wait和notify
一.多线程的执行顺序
由于多个线程执行是抢占式执行,就会导致顺序不同,同时就会导致出现问题,就比如俩个线程同时对同一个变量进行修改,我们难以预知执行顺序。
但在实际开发中,我们希望代码按一定的逻辑顺序执行,希望可以协调多个线程的执行顺序。
之前提到过join,会让调用它的线程进入阻塞等待,但有个缺陷就是,它必须得等那个线程完全执行完才能继续执行。怎么才能随意调度?
可以用到wait和notify方法
二.wait和notify
1.wait和notify可以协调多个线程的执行顺序
wait可以让指定线程进入阻塞等待状态,notify可以唤醒正在wait的线程
2.wait和notify是依赖对象的
wait和notify都是Object类里面的成员方法,它们的调用是依赖对象的
3.wait所做的工作
在了解wait所做的工作之前,我们先看一个wait和notify使用的实例:


我们发现唤醒wait之后,没有进行打印操作,而是抛出了异常,这个异常叫做:IllegalMonitorStatementException非法的监视器状态异常,什么是监视器?其实这里说的是synchronized锁,它也叫做监视器锁。这里我们就可以来了解一下wait所作的工作:
1.释放当前所持有的锁
2.让线程进入阻塞状态,并等待被唤醒。
3.当线程被唤醒时,重新获取到锁
所以说,使用wait的前提是得加锁,同时notify也得加锁,对谁加锁?就是对调用wait和notify的哪个对象进行加锁。
为什么要这样加锁呢?首先对线程1进行加锁,当它不想做任何事情时,就进入阻塞状态,此时它啥也不干,就没必要拿着锁,就释放了,让急需锁的线程2先用,当线程2的任务完成的差不多时,他就可以把锁还给线程1了。所以代码修改如下:

4.notify
唤醒正在等待的线程。当有多个线程都在等待时(前提是这几个等待的线程都在等待同一把锁),notify唤醒时是随即唤醒其中的一个线程而其他线程还在等待。并且,如果notify后面还有代码(在synronized里面),就会先执行完这些代码,再唤醒wait的线程如下例子:
public class Test2 {private static Object object=new Object();public static void main(String[] args) {Thread t1=new Thread(()->{synchronized(object) {System.out.println("t1kaishi");try {object.wait();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("t1jieshu");}});Thread t2=new Thread(()->{synchronized (object){System.out.println("t2kaishi");try {object.wait();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("t2jieshu");}});Thread t3=new Thread(()->{try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}synchronized (object){try {object.notify();Thread.sleep(1000);System.out.println("t3jieshu");} catch (InterruptedException e) {e.printStackTrace();}}});t1.start();t2.start();t3.start();}
}

首先,t1t2是等待线程,t3是通知线程。t1开始,先得到了锁,然后wait时释放了锁,这时t2拿到了锁,然后wait时释放了锁;之后等1秒过后,t3拿到了锁,然后唤醒等待该锁的线程,但我们发现,最终是t1结束了,但t2没有结束而且程序迟迟没有结束,这说明只有t1被唤醒了,而t2还在wait。而且可以发现,是t3结束先打印的,说明是notify之后会把后面的代码全部执行完才会去唤醒线程,而在调用了notify和t3后续代码执行完期间,t1的状态就是BLOCKED状态,如下:

这是在t3执行了notify之后,t1的状态:Thread-2(也就是t3)持有锁,而Thread-0(t1)已经不是waiting状态了,而是BOLCKED状态,它已经被唤醒,在等锁。
5.notifyAll
notifyAll方法是一次唤醒所有线程。这与notify不同的是,所有线程都可以从WAITING状态转变成其他状态,但是,一i那位它们都想拿同一把锁,所以会出现锁金正,没拿到锁的就得等待持有锁的把锁释放了再去竞争,在等待锁的过程中,这些线程就是BLOCKED状态
public class Test2 {private static Object object=new Object();public static void main(String[] args) {Thread t1=new Thread(()->{synchronized(object) {System.out.println("t1kaishi");try {object.wait();Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("t1jieshu");}});Thread t2=new Thread(()->{synchronized (object){System.out.println("t2kaishi");try {object.wait();Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("t2jieshu");}});Thread t3=new Thread(()->{try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}synchronized (object){try {object.notifyAll();Thread.sleep(1000);System.out.println("t3jieshu");} catch (InterruptedException e) {e.printStackTrace();}}});t1.start();t2.start();t3.start();}
}

还是上面这个代码,只不过在t1t2被唤醒后又让它们沉睡了1秒,以便观察它们的状态,这一次是notify之后,t2抢到了锁,观察jconsole.exe,发现t1和t2都是BLOCKED,因为先执行了t3锁里面的内容,然后是t2开始执行,此时t1还是BLOCKED,最后t1也拿到了锁。
6.注意
一般我们使用nootify方法,而不是用notifyAll方法,因为notify方法更加可控,而notifyAll方法却会引起竞争,而且会增加cpu的消耗
相关文章:
Java EE之wait和notify
一.多线程的执行顺序 由于多个线程执行是抢占式执行,就会导致顺序不同,同时就会导致出现问题,就比如俩个线程同时对同一个变量进行修改,我们难以预知执行顺序。 但在实际开发中,我们希望代码按一定的逻辑顺序执行&am…...
PostgreSQL中In, Exists在SQL查询中到底有无区别
前言 SQL查询当中,In和Exists子查询到底有无区别?记得很多年以前,确实是有相关的使用戒条的,或者说存在一些使用的惯用法。试图完全抹开两者的区别,就有点过了。 两者的主要区别: 从目的上讲,…...
Netty Review - 探究Netty服务端主程序无异常退出的背后机制
文章目录 概述故障场景尝试改进问题分析铺垫: Daemon线程Netty服务端启动源码分析逻辑分析 如何避免Netty服务端意外退出最佳实践 概述 在使用Netty进行服务端程序开发时,初学者可能会遇到各种问题,其中之一就是服务端意外退出的问题。这种问…...
【兔子机器人】修改GO电机id(软件方法、硬件方法)
一、硬件方法 利用上位机直接修改GO电机的id号: 打开调试助手,点击“调试”,查询电机,修改id号,即可。 但先将四个GO电机连接线拔掉,不然会将连接的电机一并修改。 利用24V电源给GO电机供电。 二、软件方…...
Spring MVC | Spring MVC 的“核心类” 和 “注解”
目录: Spring MVC 的“核心类” 和 “注解” :1.DispatcherServlet (前端控制器)2.Controller 注解3.RequestMapping 注解3.1 RequestMapping 注解的 “使用”标注在 “方法” 上标注在 “类” 上 3.2 RequestMapping 注解的 “属性” 4.组合注解4.1 请求处理方法的…...
Python 创建PPT
本篇为如何使用Python来创建ppt文件。 创建PPT 安装必要的库 命令如下: pip install python-pptx 安装过程: 创建ppt文件 在当前目录下创建一个test的ppt文件。其中包含两页,分别使用了不同的布局。 第一页设置了标题和内容。第二页只设…...
【工具】Git的24种常用命令
相关链接 传送门:>>>【工具】Git的介绍与安装<< 1.Git配置邮箱和用户 第一次使用Git软件,需要告诉Git软件你的名称和邮箱,否则无法将文件纳入到版本库中进行版本管理。 原因:多人协作时,不同的用户可…...
rabbitmq 基本总结
rabbitmq 的基本概念 vhost、broker、producer、 consumer、 exchange、 queue、 routing key rabbitmq 常用的队列类型,工作队列(简单队列),pub/sub, routing key, topic 模式 <dependency><groupId>com.rabbitmq&l…...
7、Copmose自定义颜色和主题切换
Copmose自定义颜色和主题切换 一起颜色的设置的都是在res/values/colors里面去做颜色, 但是当使用compose的时候,抛弃了使用了ui.theme底下的Color.kt和Theme.kt 但是默认使用的是MaterialTheme主题,里面的颜色字段不能定义,因此…...
js-判断变量是否定义
if (typeof myVar undefined) {// myVar (未定义) 或 (已定义但未初始化) } else {// myVar (已定义和已初始化) } 参考 https://www.cnblogs.com/redFeather/p/17662966.html...
视频远程监控平台EasyCVR集成后播放只有一帧画面的原因排查与解决
智慧安防视频监控平台EasyCVR能在复杂的网络环境中(专网、局域网、广域网、VPN、公网等)将前端海量的设备进行统一集中接入与视频汇聚管理,平台可支持的接入协议包括:国标GB28181、RTSP/Onvif、RTMP,以及厂家的私有协议…...
Pulsar 社区周报 | No.2024.03.08 Pulsar-Spark Connector 助力实时计算
关于 Apache Pulsar Apache Pulsar 是 Apache 软件基金会顶级项目,是下一代云原生分布式消息流平台,集消息、存储、轻量化函数式计算为一体,采用计算与存储分离架构设计,支持多租户、持久化存储、多机房跨区域数据复制,…...
Redis--线程模型详解
Redis线程模型 Redis内部使用的文件事件处理器(基于Reactor模式开发的)file event handler是单线程的,所以Redis线程模型才叫单线程模型,它采用IO多路复用机制同时监听多个socket,当被监听的socket准备好执行accep、r…...
[备赛笔记]——5G大唐杯(5G考试等级考考试基础试题)
个人名片: 🦁作者简介:学生 🐯个人主页:妄北y 🐧个人QQ:2061314755 🐻个人邮箱:2061314755qq.com 🦉个人WeChat:Vir2021GKBS 🐼本文由…...
【解读】OWASP 大语言模型(LLM)安全测评基准V1.0
大语言模型(LLM,Large Language Model)是指参数量巨大、能够处理海量数据的模型, 此类模型通常具有大规模的参数,使得它们能够处理更复杂的问题,并学习更广泛的知识。自2022 年以来,LLM技术在得到了广泛的应…...
java数据结构与算法刷题-----LeetCode77. 组合
java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846 文章目录 1. 递归实现 解题思路 这种题只能暴力求解,枚举所有可…...
网络安全运营的工作内容(附资料下载)
【推荐】最新网络安全运营方案和实践合集(共80多份).zip 网络安全运营的工作内容是一个多层次、多维度的体系,涵盖了多个关键领域以确保网络环境的稳定和安全。以下是一些主要的工作内容: 安全策略制定与实施: 制定网…...
华为OD面试分享13(2024年)
华为OD面经 二战失败选手,双非一本部门目标院校,数学与应用数学专业,无相关工作经验也没有什么拿得出手的项目。3月中旬开始重新学java(大学里有学过一个学期的java,很水)。期间经常通宵肝,学习框架、刷leedcode,可能是因为数学专业出身,数据结构和算法这一块学起来并…...
Android14之解决报错:No module named sepolgen(一百九十二)
简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒…...
数电学习笔记——逻辑函数的代数法化简
目录 逻辑函数的化简原则 与或逻辑的化简 1、吸收律(1) ( ABABA) 2、吸收律(2)(3)( AABA;AABAB) 3、多余项定律( ABACBCABAC) 4、拆项法 5、添项法 逻辑函数的化简原则 (1)逻辑函数所用的门最少 (2)各个门的输入端要少 (3)逻辑电路所用的级数要少 (4)逻辑…...
国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...
练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...
iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版分享
平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...
ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...
UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
探索Selenium:自动化测试的神奇钥匙
目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...
