Java中wait和notify详解

线程的调度是无序的,随机的,但是也是有一定的需求场景,希望能够有序执行,join算是一种控制顺序的方式(功能有限)——》一个线程执行完,才能执行另一个线程!

本文主要讲解的:wait和notify则有一下功能:

wait:就是让某个线程先暂停下来,等一等

notify:就是把该线程唤醒,能够继续执行

wait:发现条件不满足/时间不成熟,就先阻塞等待

notify:其他线程构造了一个成熟的条件,就可以唤醒wait的等待

wait和notify都是Object的方法,只要你是个类对象(不是基本的数据类型)都可以使用wait和notify

Object.wait主要做的三件事:

  1. 解锁(先加锁,才能解锁)
  2. 阻塞等待
  3. 当收到通知的时候,就会唤醒,同时尝试重新获取锁

wait必须写到synchronized代码块里面~

notify也是要放到synchronized中使用的~

public class Main4 {public static void main(String[] args) throws InterruptedException {Object object=new Object();//加锁对象必须和wait的对象是同一个synchronized (object){object.wait();}}
}

加锁对象必须和wait的对象是同一个

对于wait和notify而言:值得注意的是:

必须要先执行wait,然后notify,此时才有效果~
如果现在还没有wait,就notify,相当于:一炮打空(没有额外的副作用,但是代码的功能不能正确执行了!),此时wait无法唤醒,代码也不会出现其他异常~!!

我们来看一下下述代码:

public class Main5 {public static void main(String[] args) throws InterruptedException{Object locker=new Object();Thread t1= new Thread(()->{while (true){try {System.out.println("wait 开始");synchronized (locker) {locker.wait();}} catch (InterruptedException e) {e.printStackTrace();}}});t1.start();
//让t1先启动,主线程休息1秒,在主线程休息1秒的过程中,
// t1线程应该执行到:synchronized (locker) {locker.wait(); }的位置,等1秒钟数据到t2开始执行notifyThread.sleep(1000);Thread t2=new Thread(()->{synchronized (locker){System.out.println("notify 开始");locker.notify();System.out.println("notify 结束");}});t2.start();}
}

上述代码的运行结果为:

解析:t1先执行,执行到了wait就阻塞了,t1之后t2开始执行,执行到了notify就会通知t1线程开始唤醒(注意:notify是在synchronized内部,就需要t2释放了锁,t1才能继续往下走~

在上述代码中,虽然是t1先执行的,但是可以通过wait,notify控制,让t2先执行一些逻辑,t2执行完之后,notify唤醒t1,t1在继续往下执行~

使用wait阻塞等待会让线程进入WAITING状态

wait也提供了一个带参数的版本,参数指定的是最大等待时间!

不带参数的wait是死等,带参数的wait就会等到最大时间之后,还没人通知,就自己唤醒自己!!

join只能是让t2线程执行完,再继续执行t1,一定是串行的

wait和notify可以让t2线程执行完,再让t1执行……,t1执行完一部分,再让t2执行,t2在执行一部分,在让t1执行…………

对于唤醒操作,还有一个notifyAll(notify用的比较多)

可以有多个线程,等待同一个对象的情况!!如:在t1,t2,t3中都调用了object.wait,此时在main中,调用了object.notify,会随机唤醒t1,t2中的一个线程,另外两个仍然是WAITING状态!如果调用了object.notifyAll,此时就会把t1,t2,t3的三个线程都唤醒,此时三个线程就会重新竞争锁,然后依次执行……

wait和sleep的对比(面试题)

由于wait有一个带参数的版本,用来体现超时时间,这个感觉跟sleep差不多!!

wait也能提前唤醒,sleep也能提前唤醒,

wait解决的是线程之间的顺序控制,sleep单纯的是让当前线程休眠一会!

唯一相同点是:都可以让线程放弃执行一段时间!

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

wait是Object的方法,sleep是Thread的静态方法~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/127119.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【工具使用】Dependency Walker使用

一,简介 在工作过程中常常会遇到编译的dll库运行不正常的情况,那就需要确认dll库是否编译正常,即是否将函数编译到dll中去。今天介绍一种查看dll库中函数定义的工具——Dependency walker。 二,软件介绍 Dependency Walker是一…

CSS3技巧36:backdrop-filter 背景滤镜

CSS3 有 filter 滤镜属性,能给内容,尤其是图片,添加各种滤镜效果。 filter 滤镜详见博文:CSS3中强大的filter(滤镜)属性_css3滤镜_stones4zd的博客-CSDN博客 后续,CSS3 又新增了 backdrop-filter 背景滤镜。 backdr…

源码剖析:Elasticsearch 段合并调度及优化手段

1、背景 经常看到集群的merge限流耗时比较高,所以想分析其原因、造成的影响、以及反思merge的一些优化手段。 比如下图中测试集群相关监控截图: 可是从磁盘的写入来看,并不高: 那么目前的情况带来哪些影响? 资源利用率…

七大排序算法

目录 直接插入排序 希尔排序 直接选择排序 堆排序 冒泡排序 快速排序 快速排序优化 非递归实现快速排序 归并排序 非递归的归并排序 排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作. 常见的排序算法有插入排序(直接插入…

工具 | XShell的学习与使用

工具 | XShell的学习与使用 时间:2023年9月8日09:03:29 文章目录 工具 | XShell的学习与使用1.下载2.安装 1.下载 1.官网XSHELL - NetSarang Website 2.免费版下载:家庭/学校免费 - NetSarang Website (xshell.com) 3.https://cdn.netsarang.net/de06d10…

Postman接口测试流程

一、工具安装 ● 安装Postman有中文版和英文版,可以选择自己喜欢的版本即可。安装时重新选择一下安装路径(也可以默认路径),一直下一步安装完成即可。(本文档采用英文版本)安装文件网盘路径链接&#xff1…

transformer 总结(超详细-初版)

相关知识链接 attention1attention2 引言 本文主要详解 transformer 的算法结构以及理论解释,代码实现以及具体实现时候的细节放在下一篇来详述。 下面就通过上图中 transformer 的结构来依次解析 输入部分(Encode 侧) input 输出主要包含 两个部分&#xff1a…

第5篇 vue的通信框架axios和ui框架-element-ui以及node.js

一 axios的使用 1.1 介绍以及作用 axios是独立于vue的一个项目,基于promise用于浏览器和node.js的http客户端。 在浏览器中可以帮助我们完成 ajax请求的发送在node.js中可以向远程接口发送请求 1.2 案例使用axios实现前后端数据交互 1.后端代码 2.前端代码 &…

微信最新更新隐私策略(2023-08-15)

1、manifest.json 配置修改 在mp-weixin: 参数修改&#xff08;没有就添加&#xff09; "__usePrivacyCheck__": true, ***2、注意 微信开发者工具调整 不然一直报错 找不到 getPrivacySetting 废话不多说 上代码 3、 编辑首页 或者用户授权界面 <uni-popup…

【云原生】Kubeadmin部署Kubernetes集群

目录 ​编辑 一、环境准备 1.2调整内核参数 二、所有节点部署docker 三、所有节点安装kubeadm&#xff0c;kubelet和kubectl 3.1定义kubernetes源 3.2开机自启kubelet 四、部署K8S集群 4.1查看初始化需要的镜像 4.2在 master 节点上传 v1.20.11.zip 压缩包至 /opt 目录…

【Linux】文件系统

磁盘及文件系统 文件的增删查改 重新认识目录 目录是文件嘛&#xff1f; 是的。 目录有iNode嘛&#xff1f; 有 目录有内容嘛&#xff1f; 有 任何一个文件&#xff0c;一定在一个目录内部&#xff0c;所以一个目录的内容是什么&#xff1f; 需要数据块&#xff0c;目录的数据…

【技术支持案例】S32K146的hard fault问题处理

文章目录 1. 案例背景2. 方案准备2.1 HardFault&#xff08;硬件错误异常&#xff09;2.2 UsageFault&#xff08;用法错误异常&#xff09;2.3 BusFault&#xff08;总线错误异常&#xff09;2.4 MemManage Fault&#xff08;存储器管理错误异常&#xff09; 3. 现场支持3.1 现…

Java基础之static关键字

目录 静态的特点第一章、静态代码块第二章、静态属性第三章、静态方法调用静态方法时静态方法中调用非静态方法时 第四章、static关键字与其他关键字 友情提醒 先看文章目录&#xff0c;大致了解文章知识点结构&#xff0c;点击文章目录可直接跳转到文章指定位置。 静态的特点…

JVM学习(一)--程序计数器

作用&#xff1a;记住下一个jvm指令的执行地址 每一行java源代码&#xff0c;会被编译为多行jvm指令&#xff0c;上文所说的执行地址就是这里的0,3,4等 &#xff0c;由于执行访问特别频繁&#xff0c;程序计数器的底层是有寄存器来实现的 特点&#xff1a; 线程私有&#xff…

kafka学习-生产者

目录 1、消息生产流程 2、生产者常见参数配置 3、序列化器 基本概念 自定义序列化器 4、分区器 默认分区规则 自定义分区器 5、生产者拦截器 作用 自定义拦截器 6、生产者原理解析 1、消息生产流程 2、生产者常见参数配置 3、序列化器 基本概念 在Kafka中保存的数…

一文速学-让神经网络不再神秘,一天速学神经网络基础(七)-基于误差的反向传播

前言 思索了很久到底要不要出深度学习内容&#xff0c;毕竟在数学建模专栏里边的机器学习内容还有一大半算法没有更新&#xff0c;很多坑都没有填满&#xff0c;而且现在深度学习的文章和学习课程都十分的多&#xff0c;我考虑了很久决定还是得出神经网络系列文章&#xff0c;…

Linux安装kibana

相关链接 https://www.elastic.co/cn/downloads/kibana https://artifacts.elastic.co/downloads/kibana/kibana-7.5.1-linux-x86_64.tar.gz 官网下载可能比较慢&#xff0c;下面提供下载地址 百度云链接&#xff1a;https://pan.baidu.com/s/1d9Cqr9EwHF94op90F57bww 提取码…

Elasticsearch实战(五):Springboot实现Elasticsearch电商平台日志埋点与搜索热词

文章目录 系列文章索引一、提取热度搜索1、热搜词分析流程图2、日志埋点&#xff08;1&#xff09;排除logback的默认集成。&#xff08;2&#xff09;引入log4j2起步依赖&#xff08;3&#xff09;设置配置文件&#xff08;4&#xff09;配置文件模板&#xff08;5&#xff09…

计算机竞赛 基于深度学习的人脸性别年龄识别 - 图像识别 opencv

文章目录 0 前言1 课题描述2 实现效果3 算法实现原理3.1 数据集3.2 深度学习识别算法3.3 特征提取主干网络3.4 总体实现流程 4 具体实现4.1 预训练数据格式4.2 部分实现代码 5 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 毕业设计…

使用 【jacoco】对基于 SpringBoot 和 Dubbo RPC 的项目生成测试覆盖率报告:实践+原理

基于 Dubbo RPC 的项目中有一个提供者项目backend、一个消费者项目gateway、以及注册中心nacos。本篇文章记录在windows本地对该框架的测试过程&#xff0c;以及介绍jacoco的基本原理 测试过程 官网下载安装包解压到本地&#xff0c;https://www.jacoco.org/jacoco/ 只需要用…