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

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子查询到底有无区别?记得很多年以前,确实是有相关的使用戒条的,或者说存在一些使用的惯用法。试图完全抹开两者的区别,就有点过了。 两者的主要区别: 从目的上讲&#xff0c…...

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种常用命令

相关链接 传送门&#xff1a;>>>【工具】Git的介绍与安装<< 1.Git配置邮箱和用户 第一次使用Git软件&#xff0c;需要告诉Git软件你的名称和邮箱&#xff0c;否则无法将文件纳入到版本库中进行版本管理。 原因&#xff1a;多人协作时&#xff0c;不同的用户可…...

rabbitmq 基本总结

rabbitmq 的基本概念 vhost、broker、producer、 consumer、 exchange、 queue、 routing key rabbitmq 常用的队列类型&#xff0c;工作队列&#xff08;简单队列&#xff09;,pub/sub, routing key&#xff0c; topic 模式 <dependency><groupId>com.rabbitmq&l…...

7、Copmose自定义颜色和主题切换

Copmose自定义颜色和主题切换 一起颜色的设置的都是在res/values/colors里面去做颜色&#xff0c; 但是当使用compose的时候&#xff0c;抛弃了使用了ui.theme底下的Color.kt和Theme.kt 但是默认使用的是MaterialTheme主题&#xff0c;里面的颜色字段不能定义&#xff0c;因此…...

js-判断变量是否定义

if (typeof myVar undefined) {// myVar (未定义) 或 (已定义但未初始化) } else {// myVar (已定义和已初始化) } 参考 https://www.cnblogs.com/redFeather/p/17662966.html...

视频远程监控平台EasyCVR集成后播放只有一帧画面的原因排查与解决

智慧安防视频监控平台EasyCVR能在复杂的网络环境中&#xff08;专网、局域网、广域网、VPN、公网等&#xff09;将前端海量的设备进行统一集中接入与视频汇聚管理&#xff0c;平台可支持的接入协议包括&#xff1a;国标GB28181、RTSP/Onvif、RTMP&#xff0c;以及厂家的私有协议…...

Pulsar 社区周报 | No.2024.03.08 Pulsar-Spark Connector 助力实时计算

关于 Apache Pulsar Apache Pulsar 是 Apache 软件基金会顶级项目&#xff0c;是下一代云原生分布式消息流平台&#xff0c;集消息、存储、轻量化函数式计算为一体&#xff0c;采用计算与存储分离架构设计&#xff0c;支持多租户、持久化存储、多机房跨区域数据复制&#xff0c…...

Redis--线程模型详解

Redis线程模型 Redis内部使用的文件事件处理器&#xff08;基于Reactor模式开发的&#xff09;file event handler是单线程的&#xff0c;所以Redis线程模型才叫单线程模型&#xff0c;它采用IO多路复用机制同时监听多个socket&#xff0c;当被监听的socket准备好执行accep、r…...

[备赛笔记]——5G大唐杯(5G考试等级考考试基础试题)

个人名片&#xff1a; &#x1f981;作者简介&#xff1a;学生 &#x1f42f;个人主页&#xff1a;妄北y &#x1f427;个人QQ&#xff1a;2061314755 &#x1f43b;个人邮箱&#xff1a;2061314755qq.com &#x1f989;个人WeChat&#xff1a;Vir2021GKBS &#x1f43c;本文由…...

【解读】OWASP 大语言模型(LLM)安全测评基准V1.0

大语言模型&#xff08;LLM&#xff0c;Large Language Model&#xff09;是指参数量巨大、能够处理海量数据的模型, 此类模型通常具有大规模的参数&#xff0c;使得它们能够处理更复杂的问题&#xff0c;并学习更广泛的知识。自2022 年以来&#xff0c;LLM技术在得到了广泛的应…...

java数据结构与算法刷题-----LeetCode77. 组合

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 文章目录 1. 递归实现 解题思路 这种题只能暴力求解&#xff0c;枚举所有可…...

网络安全运营的工作内容(附资料下载)

【推荐】最新网络安全运营方案和实践合集&#xff08;共80多份&#xff09;.zip 网络安全运营的工作内容是一个多层次、多维度的体系&#xff0c;涵盖了多个关键领域以确保网络环境的稳定和安全。以下是一些主要的工作内容&#xff1a; 安全策略制定与实施&#xff1a; 制定网…...

华为OD面试分享13(2024年)

华为OD面经 二战失败选手,双非一本部门目标院校,数学与应用数学专业,无相关工作经验也没有什么拿得出手的项目。3月中旬开始重新学java(大学里有学过一个学期的java,很水)。期间经常通宵肝,学习框架、刷leedcode,可能是因为数学专业出身,数据结构和算法这一块学起来并…...

Android14之解决报错:No module named sepolgen(一百九十二)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…...

数电学习笔记——逻辑函数的代数法化简

目录 逻辑函数的化简原则 与或逻辑的化简 1、吸收律(1) ( ABABA) 2、吸收律(2)(3)( AABA&#xff1b;AABAB) 3、多余项定律( ABACBCABAC) 4、拆项法 5、添项法 逻辑函数的化简原则 (1)逻辑函数所用的门最少 (2)各个门的输入端要少 (3)逻辑电路所用的级数要少 (4)逻辑…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

golang循环变量捕获问题​​

在 Go 语言中&#xff0c;当在循环中启动协程&#xff08;goroutine&#xff09;时&#xff0c;如果在协程闭包中直接引用循环变量&#xff0c;可能会遇到一个常见的陷阱 - ​​循环变量捕获问题​​。让我详细解释一下&#xff1a; 问题背景 看这个代码片段&#xff1a; fo…...

通过Wrangler CLI在worker中创建数据库和表

官方使用文档&#xff1a;Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后&#xff0c;会在本地和远程创建数据库&#xff1a; npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库&#xff1a; 现在&#xff0c;您的Cloudfla…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)

要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况&#xff0c;可以通过以下几种方式模拟或触发&#xff1a; 1. 增加CPU负载 运行大量计算密集型任务&#xff0c;例如&#xff1a; 使用多线程循环执行复杂计算&#xff08;如数学运算、加密解密等&#xff09;。运行图…...

爬虫基础学习day2

# 爬虫设计领域 工商&#xff1a;企查查、天眼查短视频&#xff1a;抖音、快手、西瓜 ---> 飞瓜电商&#xff1a;京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空&#xff1a;抓取所有航空公司价格 ---> 去哪儿自媒体&#xff1a;采集自媒体数据进…...

08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险

C#入门系列【类的基本概念】&#xff1a;开启编程世界的奇妙冒险 嘿&#xff0c;各位编程小白探险家&#xff01;欢迎来到 C# 的奇幻大陆&#xff01;今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类&#xff01;别害怕&#xff0c;跟着我&#xff0c;保准让你轻松搞…...

在 Spring Boot 项目里,MYSQL中json类型字段使用

前言&#xff1a; 因为程序特殊需求导致&#xff0c;需要mysql数据库存储json类型数据&#xff0c;因此记录一下使用流程 1.java实体中新增字段 private List<User> users 2.增加mybatis-plus注解 TableField(typeHandler FastjsonTypeHandler.class) private Lis…...

绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化

iOS 应用的发布流程一直是开发链路中最“苹果味”的环节&#xff1a;强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说&#xff0c;这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发&#xff08;例如 Flutter、React Na…...

相关类相关的可视化图像总结

目录 一、散点图 二、气泡图 三、相关图 四、热力图 五、二维密度图 六、多模态二维密度图 七、雷达图 八、桑基图 九、总结 一、散点图 特点 通过点的位置展示两个连续变量之间的关系&#xff0c;可直观判断线性相关、非线性相关或无相关关系&#xff0c;点的分布密…...