news 2026/3/26 1:12:48

wait和notify

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
wait和notify

wait和notify是协调线程之间执行逻辑的顺序的功能,他和join和synchronized的区别是什么呢?join指的是等待一个线程的结束,这个线程才结束,也就是假如我在main线程中使用了t1.join代表的是main线程得等到t1线程结束了他才能结束;synchronized呢是代表锁的意思,意思是当两个线程使用同一个对象来进行锁时,他们二者之间只能有一个线程使用这个锁,来一个线程必须堵塞等待这个使用锁的线程结束才有机会使用这个“钥匙”。

wait和notify呢?他代表的是我在某个锁里边使用wait时,运行到wait这个关键字这个锁就会在wait关键字这进行堵塞等待,堵塞等待的过程中就会把wait所在的锁释放出去,供给其他锁使用,直到有线程运行到notify关键字才会通知wait关键字可以使用了,但通知归通知,wait想要再次获得锁必须得“竞争”。

wait和notif有什么作用呢?举个很简单了例子,把每一个线程当成鸟宝宝,CPU当成鸟妈妈,鸟宝宝会竞争鸟妈妈带回来的虫子(资源)吃,当一个一个线程一直迟到虫子,其他虫子就会饿死,这是我们就要使用wait和notify了,这两个关键字可以让吃过虫子的鸟宝宝等待通知才去竞争虫子,把资源让给其他鸟宝宝,而这里的饿死也是计算机中的“饿死”

wait

我们先聊聊wait:

public class Dome15 { public static void main(String[] args) throws InterruptedException { Object object = new Object(); Thread t1 = new Thread(()->{ System.out.println("你好,t1"); try { object.wait(); } catch (InterruptedException e) { throw new RuntimeException(e); } }); t1.start(); t1.join(); } }

当我们直接使用wait时,Java会报错,为什么呢?我们想想我们使用wait是为了什么?不就是为了把锁的资源让给其他线程使用吗?这里不加锁那使用wait有什么意义呢?故而在使用wait前得先加锁才能使用:

public class Dome15 { public static void main(String[] args) throws InterruptedException { Object object = new Object(); Thread t1 = new Thread(()->{ System.out.println("你好,t1"); try { synchronized(object){ object.wait(); } } catch (InterruptedException e) { throw new RuntimeException(e); } }); t1.start(); t1.join(); } }

当我们加完锁之后就会发现这个线程能正常的运行了,但他一直在堵塞等待,这是就需要用到notify关键字来通知他了;

这个wait关键字的意思呢是当进入synchronized关键字加锁,遇到wait关键字解锁等待遇到notify关键字通知他可以竞争“钥匙”l,竞争到钥匙又会加锁,遇到“}”又解锁供其他线程使用

但我们有一点需要注意的是wait是Object的一个方法,所有所有类都继承了wait关键字;我们在使用wait关键字时必须得让锁的对象和他一至,为什么要一至呢?这就得考虑到wait的意义了,他的期望就是把锁释放出去给其他人使用,而他释放的是嵌套他的锁,如果不一致那他释放锁的意义是什么?。

notify

前面我们聊到notify的主要作用是为了通知wait可以去竞争锁了,我们写一段代码来感受感受notify的作用

public class Dome15 { public static void main(String[] args) throws InterruptedException { Object object = new Object(); Thread t1 = new Thread(()->{ try { synchronized(object){ System.out.println("开启,t1"); object.wait(); System.out.println("结束。t1"); } } catch (InterruptedException e) { throw new RuntimeException(e); } }); Thread t2 = new Thread(()->{ try { Thread.sleep(1); } catch (InterruptedException e) { throw new RuntimeException(e); } synchronized (object){ Scanner sc = new Scanner(System.in); System.out.println("输入任意数唤醒t1:"); sc.next(); object.notify(); } }); t1.start(); t2.start(); t1.join(); t2.join(); } }

notify的作用呢就是通知wait可以竞争锁了;这里我们需要注意的是notify和wait连个关键字的引用必须满足是同一个对象,而synchronized之间又必须是同一个对象,使用他们四个必须是同一个对象间的引用。

此时有一个问题,如果有多个wait时,notify会怎么办呢?

public class Dome15 { public static void main(String[] args) throws InterruptedException { Object object = new Object(); Thread t1 = new Thread(()->{ try { synchronized(object){ System.out.println("开启,t1"); object.wait(); System.out.println("结束。t1"); } } catch (InterruptedException e) { throw new RuntimeException(e); } }); Thread t3 = new Thread(()->{ try { synchronized(object){ System.out.println("开启,t3"); object.wait(); System.out.println("结束。t3"); } } catch (InterruptedException e) { throw new RuntimeException(e); } }); Thread t2 = new Thread(()->{ try { Thread.sleep(1); } catch (InterruptedException e) { throw new RuntimeException(e); } synchronized (object){ Scanner sc = new Scanner(System.in); System.out.println("输入任意数唤醒t1:"); sc.next(); object.notify(); } }); t1.start(); t3.start(); t2.start(); t1.join(); t3.join(); t2.join(); } }

此时他就会随机通知一个wait;但Java中哟有一个notifyAll可以通知所有wait,但不常用故而就不讨论了。

再谈wait

我们知道join有个特别重要的功能,就是可以设计等待的时间,毕竟很多计算机都是度秒如年,那wait中有没有呢?答案是有的。wait也是和join一样若等待时间超过规定的时间就会去竞争锁。此时我们会发现一个现象,wait如果加了等待时间会和sleep非常相像,但wait可以被提前唤醒sleep只能通过Interrupt来唤醒,但Interrput的主要功能并不是用来唤醒的,故而sleep在开发中斌不常用。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/26 4:57:58

TinyPro移动端适配方案的技术拆解

本文由TinyPro贡献者王晨光同学原创。 一、背景:让 TinyPro 真正“走到掌心里” TinyPro 是一套基于 TinyVue 打造的前后端分离后台管理系统,支持菜单配置、国际化、多页签、权限管理等丰富特性。 TinyPro 在桌面端具备良好的体验和模块化架构&#xf…

作者头像 李华
网站建设 2026/3/26 2:08:40

Java性能优化实战:20个核心技巧与案例

Java性能优化实战技术文章大纲性能优化的核心原则明确优化目标:响应时间、吞吐量、资源利用率遵循80/20法则,优先解决瓶颈问题测量优于猜测,基于数据驱动决策避免过度优化导致的代码可维护性下降JVM层优化策略内存管理优化:堆大小…

作者头像 李华
网站建设 2026/3/24 20:34:48

战略即增长:解析中网、里斯、特劳特赋能产业标杆的差异化“杀手锏

本文将详细分析中网、里斯和特劳特在战略赋能方面的各自优势与方法。首先,战略赋能的核心在于帮助企业提升竞争力和应对市场变化。接着,文章将探讨中网如何通过技术驱动和B2B增长方法,增强客户的市场响应能力。里斯则采用品类战略&#xff0c…

作者头像 李华
网站建设 2026/3/25 20:46:44

LLM知识随笔(二)--BERT

LLM知识随笔(二)–BERT 文章目录 LLM知识随笔(二)--BERT一、BERT:公认的里程碑1. BERT与GPT之间的区别:2.单向编码与双向编码的区别 二、BERT的结构:强大的特征提取能力1.ELMo、GPT、BERT三者区…

作者头像 李华
网站建设 2026/3/25 13:34:13

【软件测试】1_性能测试 _Locust简介安装

文章目录 一、Locust简介1.1 特点 二、Locust安装2.1 命令安装2.2 pycharm安装 一、Locust简介 Locust是一个开源的性能测试工具,主要思想就是模拟一群用户访问你的系统。 1.1 特点 1、在代码中定义用户行为 不需要安装笨重的软件, 只是简单的Python…

作者头像 李华
网站建设 2026/3/11 6:44:52

java_ssm62海洋馆水族馆管理系统

目录具体实现截图海洋馆水族馆管理系统摘要系统所用技术介绍写作提纲源码文档获取/同行可拿货,招校园代理 :文章底部获取博主联系方式!具体实现截图 海洋馆水族馆管理系统摘要 海洋馆水族馆管理系统是基于Java SSM(SpringSpringMVCMyBatis&…

作者头像 李华