等待唤醒案例分析(线程之间的通信)
方法说明void wait()线程等待,等待的过程中线程会释放锁,需要被其他线程调用notify方法将其唤醒,重新抢锁执行但是并不会重新执行全部代码void notify()线程唤醒,一次唤醒一个等待线程;如果有多条线程等待,则随机唤醒一条等待线程void notifyAll()唤醒所有等待线程wait和notify方法需要锁对象调用,所以需要用到同步代码块中,而且必须是同一个锁对象2.等待唤醒案例实现/* count和flag可以定义成包装类 但是要记得给count和flag手动赋值 不然对于本案例来说,容易出现空指针异常 */ public class BaoZiPu { //代表包子的count private int count; //代表是否有包子的flag private boolean flag; public BaoZiPu() { } public BaoZiPu(int count, boolean flag) { this.count count; this.flag flag; } /* getCount 改造成消费包子方法 直接输出count */ public void getCount() { System.out.println(消费了..............第count个包子); } /* setCount 改造成生产包子 count */ public void setCount() { count; System.out.println(生产了...第count个包子); } public boolean isFlag() { return flag; } public void setFlag(boolean flag) { this.flag flag; } }public class Product implements Runnable{ private BaoZiPu baoZiPu; public Product(BaoZiPu baoZiPu) { this.baoZiPu baoZiPu; } Override public void run() { while(true){ try { Thread.sleep(100L); } catch (InterruptedException e) { throw new RuntimeException(e); } synchronized (baoZiPu){ //1.判断flag是否为true,如果是true,证明有包子,生产线程等待 if (baoZiPu.isFlag()true){ try { baoZiPu.wait(); } catch (InterruptedException e) { throw new RuntimeException(e); } } //2.如果flag为false,证明没有包子,开始生产 baoZiPu.setCount(); //3.改变flag状态,为true,证明生产完了,有包子了 baoZiPu.setFlag(true); //4.唤醒消费线程 baoZiPu.notify(); } } } }public class Consumer implements Runnable{ private BaoZiPu baoZiPu; public Consumer(BaoZiPu baoZiPu) { this.baoZiPu baoZiPu; } Override public void run() { while(true){ try { Thread.sleep(100L); } catch (InterruptedException e) { throw new RuntimeException(e); } synchronized (baoZiPu){ //1.判断flag是否为false,如果是false,证明没有包子,消费线程等待 if (baoZiPu.isFlag()false){ try { baoZiPu.wait(); } catch (InterruptedException e) { throw new RuntimeException(e); } } //2.如果flag为true,证明有包子,开始消费 baoZiPu.getCount(); //3.改变flag状态,为false,证明消费完了,没 有包子了 baoZiPu.setFlag(false); //4.唤醒生产线程 baoZiPu.notify(); } } } }public class Test01 { public static void main(String[] args) { BaoZiPu baoZiPu new BaoZiPu(); Product product new Product(baoZiPu); Consumer consumer new Consumer(baoZiPu); Thread t1 new Thread(product); Thread t2 new Thread(consumer); t1.start(); t2.start(); } }总结在该实例中我们要考虑的是同步和互斥的问题我们要实现生产一个消费一个并且仅仅只有一个生产者和消费者这就要考虑到两个线程访问同一个资源的问题我们利用同步代码进行上锁处理还需要考虑生产和消费者的顺序问题我们使用wait和notify两个api进行实现。​ 我们利用同步代码在消费者和生产者中进行重写了run方法我们利用对象实例进行作为mutex互斥锁利用一个变量来判断是否已经生产还是消费若判断成功则放在该实例对象的等待队列中否则进行操作然后随机唤醒等待队列的进程。3.用同步方法改造等待唤醒案例/* count和flag可以定义成包装类 但是要记得给count和flag手动赋值 不然对于本案例来说,容易出现空指针异常 */ public class BaoZiPu { //代表包子的count private int count; //代表是否有包子的flag private boolean flag; public BaoZiPu() { } public BaoZiPu(int count, boolean flag) { this.count count; this.flag flag; } /* getCount 改造成消费包子方法 直接输出count */ public synchronized void getCount() { //1.判断flag是否为false,如果是false,证明没有包子,消费线程等待 if (this.flag false) { try { this.wait(); } catch (InterruptedException e) { throw new RuntimeException(e); } } //2.如果flag为true,证明有包子,开始消费 System.out.println(消费了..............第 count 个包子); //3.改变flag状态,为false,证明消费完了,没 有包子了 this.flag false; //4.唤醒生产线程 this.notify(); } /* setCount 改造成生产包子 count */ public synchronized void setCount() { //1.判断flag是否为true,如果是true,证明有包子,生产线程等待 if (this.flag true) { try { this.wait(); } catch (InterruptedException e) { throw new RuntimeException(e); } } //2.如果flag为false,证明没有包子,开始生产 count; System.out.println(生产了...第 count 个包子); //3.改变flag状态,为true,证明生产完了,有包子了 this.flag true; //4.唤醒消费线程 this.notify(); } public boolean isFlag() { return flag; } public void setFlag(boolean flag) { this.flag flag; } }public class Product implements Runnable{ private BaoZiPu baoZiPu; public Product(BaoZiPu baoZiPu) { this.baoZiPu baoZiPu; } Override public void run() { while(true){ try { Thread.sleep(100L); } catch (InterruptedException e) { throw new RuntimeException(e); } baoZiPu.setCount(); } } }public class Consumer implements Runnable{ private BaoZiPu baoZiPu; public Consumer(BaoZiPu baoZiPu) { this.baoZiPu baoZiPu; } Override public void run() { while(true){ try { Thread.sleep(100L); } catch (InterruptedException e) { throw new RuntimeException(e); } baoZiPu.getCount(); } } }public class Test01 { public static void main(String[] args) { BaoZiPu baoZiPu new BaoZiPu(); Product product new Product(baoZiPu); Consumer consumer new Consumer(baoZiPu); Thread t1 new Thread(product); Thread t2 new Thread(consumer); t1.start(); t2.start(); } }

相关新闻

2007-2024年上市公司人工智能投资水平数据+stata代码

2007-2024年上市公司人工智能投资水平数据+stata代码

本数据参考李果(2024)对企业人工智能投资水平指标的衡量和测算的方法,团队依据上市公司财务报告附注信息,采用关键词筛选法,整理形成人工智能投资水平数据整理说明:1.人工智能无形资产投资金额:…

2026/6/30 5:58:25阅读更多 →
青年 | 当代年轻人的「主体性觉醒」,需要一台懂自己的笔记本电脑

青年 | 当代年轻人的「主体性觉醒」,需要一台懂自己的笔记本电脑

你的节奏,何必迁就工具选笔记本这件事,说到底是在选一种相处方式——它能不能跟上你的思路,能不能接住你的习惯,都非常重要。今天小A为大家种草的这台华硕无畏Pro14 2026,或许就是一个把「你怎么用」放在第一位的选择。…

2026/6/30 5:58:25阅读更多 →
Electron 桌面应用如何接入 Microsoft Store 订阅与永久许可证

Electron 桌面应用如何接入 Microsoft Store 订阅与永久许可证

agiCode Desktop 是个 Electron 应用,通过 Microsoft Store 分发。商业化上其实也就两类产品:一类是 Sponsor Plan(赞助者订阅,Store ID 9N0BTGWV23M1),按月、按年续费,像一段需要不断浇水的感情…

2026/6/30 5:58:25阅读更多 →
前端开发基础面试-css

前端开发基础面试-css

一、 盒模型(必考送分题)面试官问: “说一说你对盒模型的理解,box-sizing 有什么用?”标准盒模型(W3C):width 内容宽度(content)。padding 和 border 会向外…

2026/6/30 6:53:28阅读更多 →
电动火箭E-Rocket的推力矢量控制与航电系统设计

电动火箭E-Rocket的推力矢量控制与航电系统设计

1. 低成本电动火箭E-Rocket的设计理念在航天技术领域,推力矢量控制(TVC)一直是实现飞行器精准操控的核心技术。传统液体燃料火箭虽然推力强大,但其复杂的燃料系统和高温燃气舵面机构使得TVC系统成本高昂且维护困难。我们团队开发的E-Rocket电动火箭平台&…

2026/6/30 6:53:28阅读更多 →
TestDisk终极指南:5步快速找回丢失分区,免费恢复宝贵数据

TestDisk终极指南:5步快速找回丢失分区,免费恢复宝贵数据

TestDisk终极指南:5步快速找回丢失分区,免费恢复宝贵数据 【免费下载链接】testdisk TestDisk & PhotoRec 项目地址: https://gitcode.com/gh_mirrors/te/testdisk 你是否曾经遇到过硬盘分区突然消失的绝望时刻?重要的工作文档、珍…

2026/6/30 6:53:28阅读更多 →
免费开源的终极卡拉OK游戏:5分钟带你玩转UltraStar Deluxe

免费开源的终极卡拉OK游戏:5分钟带你玩转UltraStar Deluxe

免费开源的终极卡拉OK游戏:5分钟带你玩转UltraStar Deluxe 【免费下载链接】USDX The free and open source karaoke singing game UltraStar Deluxe, inspired by Sony SingStar™ 项目地址: https://gitcode.com/gh_mirrors/us/USDX 你是否梦想拥有一个私人…

2026/6/30 6:53:28阅读更多 →
SubtitleEdit语音转文字实战配置与优化指南

SubtitleEdit语音转文字实战配置与优化指南

SubtitleEdit语音转文字实战配置与优化指南 【免费下载链接】subtitleedit the subtitle editor :) 项目地址: https://gitcode.com/gh_mirrors/su/subtitleedit SubtitleEdit作为一款功能强大的开源字幕编辑工具,其语音转文字功能凭借多引擎支持和智能后处理…

2026/6/30 6:53:28阅读更多 →
专业geo搜索优化公司怎么选?一文理清核心要点

专业geo搜索优化公司怎么选?一文理清核心要点

很多用户在寻找专业geo搜索优化公司时,常会面临信息繁杂、难以甄别资质的问题,本文将从多个维度梳理选择思路,帮助用户明确需求。 随着生成式AI搜索引擎的普及,企业需要通过针对性的优化手段,让自身信息出现在主流AI搜…

2026/6/30 6:48:28阅读更多 →
AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

6个月前的2025年12月,Boris Cherny 公开宣布自己卸载了 IDE。一时间,Vibe Coding 成了全行业最热的话题。6个月后,当我们回过头来拉一份真实账本,发现事情远没有"一句话生成一个App"那么浪漫。本文从产品经理和研发两个…

2026/6/30 4:03:30阅读更多 →
审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

引言:审计结束三个月了,审计员的权限还没关某城商行每年按照监管要求开展至少一次数据安全审计。审计期间,内审部门需要抽样检查各类业务数据——交易流水、客户信息、员工操作日志、权限配置记录。这些数据分布在不同系统中,审计…

2026/6/30 4:36:27阅读更多 →
为什么你需要Destiny 2 Solo Enabler:技术原理与实战指南

为什么你需要Destiny 2 Solo Enabler:技术原理与实战指南

为什么你需要Destiny 2 Solo Enabler:技术原理与实战指南 【免费下载链接】Destiny-2-Solo-Enabler Repo containing the C# and XAML code for the D2SE program. Included is also the dependency for the program, and image asset. 项目地址: https://gitcode…

2026/6/30 0:02:58阅读更多 →
第六章:PowerPoint 2010 核心功能与实战应用 —— 从入门到精通

第六章:PowerPoint 2010 核心功能与实战应用 —— 从入门到精通

1. PowerPoint 2010基础操作全攻略 刚接触PowerPoint 2010时,很多人会被它复杂的界面吓到。其实只要掌握几个核心区域,就能快速上手。我最开始用PPT时,经常找不到功能按钮在哪,后来发现主要操作都集中在顶部功能区。 工作窗口主要…

2026/6/30 0:02:58阅读更多 →
XGBoost超参数实战:从理论到调优策略

XGBoost超参数实战:从理论到调优策略

1. XGBoost超参数基础认知 第一次接触XGBoost时,我被它那密密麻麻的参数列表吓到了。这感觉就像面对一架波音747的驾驶舱——每个按钮都可能有神奇的效果,但按错了就可能坠机。经过多年实战,我发现其实掌握十几个核心参数就能解决90%的问题。…

2026/6/30 0:02:59阅读更多 →