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

等待唤醒机制两种实现方法-阻塞队列

在这里插入图片描述
桌子上有面条-》吃货执行
桌子上没面条-》生产者制造执行
在这里插入图片描述

1、消费者等待

消费者先抢到CPU执行权,发现桌子上没有面条,于是变成等待wait状态,并释放CPU执行权,此时的CPU肯定会被厨师抢到,初始开始做面条,当厨师做完后会对吃货进行提示,notify唤醒吃货来吃。
在这里插入图片描述
在这里插入图片描述

2、生产者等待

厨师先抢到CUP执行权,但是桌子上有面条,就不能再制作面条,只能等待消费者吃完面条才能做,消费者吃完后需要唤醒厨师继续做
在这里插入图片描述
代码逻辑:
在这里插入图片描述
厨师:

public class Cook extends Thread{@Overridepublic void run() {//1循环//2同步代码块//3共享数据是否到末尾,Yes//4共享数据是否到末尾,Nowhile (true){synchronized (Desk.lock){if (Desk.count==0){break;//10碗吃完}else {//厨师的核心逻辑//01判断桌子上是否有食物if (Desk.foodflag==1){//02有食物就等待try {Desk.lock.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}}else {//03没有System.out.println(Thread.currentThread().getName()+"制作食物");//04改变桌子状态Desk.foodflag=1;//05唤醒消费者吃Desk.lock.notifyAll();}}}}}
}

吃货:

public class Customer extends Thread{@Overridepublic void run() {while (true){synchronized (Desk.lock){if (Desk.count==0){break;//10碗吃完}else {//吃货的核心逻辑/** 1.判断桌子上有无面条* 2.没有:自己等待,* 3.有:吃完,并唤醒厨师做面条,count--* 4.修改桌子状态*/if (Desk.foodflag==0){//1.判断桌子上有无面条try {Desk.lock.wait();//2.没有:自己等待,} catch (InterruptedException e) {throw new RuntimeException(e);}}else {//3.有:吃完,并唤醒厨师做面条,count--Desk.count--;System.out.println(Thread.currentThread().getName()+"还能再吃"+Desk.count+"碗");Desk.lock.notifyAll();//4.修改桌子状态Desk.foodflag=0;}}}}}
}

桌子:

public class Desk {//通过变量来控制 0:没食物  1:有食物public static int foodflag=0;//总个数,最多做十碗public static int count=10;//锁对象public static Object lock=new Object();
}

//测试类

public class Test {public static void main(String[] args) {Customer customer = new Customer();Cook cook = new Cook();customer.setName("吃货");cook.setName("厨师");customer.start();cook.start();}
}

3、阻塞队列实现

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

接口无法new对象,只能通过两个实现类,第一个可以自定义队列长度。
注意:生产者与消费者必须针对同一个阻塞队列,阻塞队列可以创建在测试类中
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
厨师:

public class Cook extends Thread{ArrayBlockingQueue<String> queue;//创建构造函数,创建对象的时候进行赋值,指定同一个阻塞队列public Cook(ArrayBlockingQueue<String> queue) {this.queue = queue;}@Overridepublic void run() {while (true){try {queue.put("面条");System.out.println("厨师做了一碗面条");} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}

消费者:

public class Customer extends Thread{ArrayBlockingQueue<String> queue;public Customer(ArrayBlockingQueue<String> queue) {this.queue = queue;}@Overridepublic void run() {while (true){try {String food=queue.take();//tack底层也进行了加锁,不需要我们自己定义System.out.println("获取食物"+food);} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}

测试类:

public class Test {public static void main(String[] args) {ArrayBlockingQueue<String> queue=new ArrayBlockingQueue<>(1);Customer customer = new Customer(queue);Cook cook = new Cook(queue);customer.setName("吃货");cook.setName("厨师");customer.start();cook.start();}
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【OpenCV C++20 学习笔记】图像缩放-高斯金字塔
  • Stable Diffusion绘画 | 文生图-高分辨率修复-Hires.fix
  • 图的同态Graph Homomorphism与同构Graph Isomorphism
  • ESP IDF 4.4工程迁移到IDF5最新注意事项
  • 从核心到边界:六边形、洋葱与COLA架构的深度解析
  • uni-app中使用支付宝扫码插件并且在真机调试时使用(详细教程)
  • 3.11.样式迁移
  • Linux查看进程和进程号的几种方式
  • 数据结构第十讲:二叉树OJ题
  • 什么是人工智能 (AI)
  • 【MySQL】常用数据类型
  • Js在线Eval加密混淆及解密运行
  • [CR]厚云填补_SEGDNet
  • MySQL数据库入门:掌握数据管理的关键步骤!
  • 基于微信小程序的游戏王交流平台设计与实现-计算机毕设 附源码 06533
  • [微信小程序] 使用ES6特性Class后出现编译异常
  • CSS中外联样式表代表的含义
  • ES6简单总结(搭配简单的讲解和小案例)
  • Git的一些常用操作
  • JavaScript设计模式之工厂模式
  • java概述
  • js对象的深浅拷贝
  • spring security oauth2 password授权模式
  • spring学习第二天
  • Twitter赢在开放,三年创造奇迹
  • vue从创建到完整的饿了么(11)组件的使用(svg图标及watch的简单使用)
  • 编写符合Python风格的对象
  • 大主子表关联的性能优化方法
  • 基于django的视频点播网站开发-step3-注册登录功能 ...
  • ​​快速排序(四)——挖坑法,前后指针法与非递归
  • ​Benvista PhotoZoom Pro 9.0.4新功能介绍
  • ​HTTP与HTTPS:网络通信的安全卫士
  • ​浅谈 Linux 中的 core dump 分析方法
  • # Maven错误Error executing Maven
  • $.ajax,axios,fetch三种ajax请求的区别
  • $.each()与$(selector).each()
  • (Forward) Music Player: From UI Proposal to Code
  • (PySpark)RDD实验实战——取最大数出现的次数
  • (力扣)1314.矩阵区域和
  • (每日一问)基础知识:堆与栈的区别
  • .NET CLR Hosting 简介
  • .NET 将混合了多个不同平台(Windows Mac Linux)的文件 目录的路径格式化成同一个平台下的路径
  • .NET 实现 NTFS 文件系统的硬链接 mklink /J(Junction)
  • .Net 转战 Android 4.4 日常笔记(4)--按钮事件和国际化
  • .NET/C# 在 64 位进程中读取 32 位进程重定向后的注册表
  • .NET/C# 阻止屏幕关闭,阻止系统进入睡眠状态
  • .NetCore项目nginx发布
  • .vimrc 配置项
  • [ linux ] linux 命令英文全称及解释
  • [ Linux 长征路第二篇] 基本指令head,tail,date,cal,find,grep,zip,tar,bc,unname
  • [000-01-022].第06节:RabbitMQ中的交换机介绍
  • [7] CUDA之常量内存与纹理内存
  • [acm算法学习] 后缀数组SA
  • [AutoSAR 存储] 汽车智能座舱的存储需求
  • [BZOJ5125]小Q的书架(决策单调性+分治DP+树状数组)