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

news2025/2/16 2:44:19

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

1、消费者等待

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

2、生产者等待

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

public class Cook extends Thread{
    @Override
    public void run() {
        //1循环
        //2同步代码块
        //3共享数据是否到末尾,Yes
        //4共享数据是否到末尾,No
        while (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{
    @Override
    public 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;
    }

    @Override
    public 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;
    }

    @Override
    public 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();
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

南京观海微电子----使用运算放大器过零检测器电路图

使用运算放大器的过零检测电路 过零检测电路是运算放大器作为比较器的一种应用。它用于跟踪正弦波形在越过零电压时从正变为负或从负变为正的变化。它也可以用作方波发生器。过零检测器有许多应用&#xff0c;如时间标记发生器、相位计、频率计数器等。过零检测器可以用多种…

基于FPGA的数字信号处理(22)--进位保存加法器(Carry Save Adder, CSA)

目录 1、拆解多个数的加法 2、进位保存加法器 3、CSA的优点和缺点 4、CSA电路的实现 文章总目录点这里&#xff1a;《基于FPGA的数字信号处理》专栏的导航与说明 1、拆解多个数的加法 考虑3个4bits数相加&#xff0c;10 4 7 21 的过程是这样的&#xff1a; 其中的红色数…

【树莓派】初始化配置(自动连wifi,自动开启SSH)换清华源,远程桌面连接

@TOC 【树莓派】初始化配置(自动连wifi,自动开启SSH)换清华源 一 .烧录系统 二 .自动连wifi,自动开启SSH 三.插电启动派 四.找到树莓派的IP,SSH连接(默认账密 pi:raspberry) 五.更改清华源 注意:按快捷键ctrl+x,会提示是否保存,按Y键确认即可 1.sudo nano /etc/apt/sourc…

java面向对象编程入门

一、前言&#xff1a; 在Java中&#xff0c;面向对象编程&#xff08;Object-Oriented Programming, OOP&#xff09;是一种核心的编程范式。Java的设计和开发都是基于面向对象的思想。面向对象编程的主要目的是提高代码的可重用性、灵活性和可维护性。以下是Java面向对象编程…

在windows本地机搭建gitlab

在windows本地机搭建gitlab 1. 解决方案2. docker安装gitlab2.1 下载Docker Desktop2.2 安装gitlab的docker2.3 配置gitlab网页2.3 配置gitlab配置文件 3. frp端口转发4. ssh密钥配置5. 运行 1. 解决方案 注&#xff1a;gitlab只有linux版本&#xff0c;并不存在windows版本&a…

小柴带你学AutoSar系列三、标准和规范篇(2)BSWGeneral

BSWDistributionGuide BSW在AUTOSAR架构中的这里哦 BSW Distribution in Multi-Core Systems BSW Functional Clusters BSW功能集群是一组相关功能的模块 BSW functional clusters are groups of functionally coherent BSW modules. The following types of clusters might…

如何搭建云电脑?让数据更安全。。。。。。

上周,微软Windows系统的蓝屏故障对各行各业造成了严重影响。航空业首当其冲,当天所有航班停飞,人员滞留在机场。 酒店业也未能幸免,同样受到波及。 1. 故障分析及解决措施 本次蓝屏事件的导火索是CrowdStrike公司更新的驱动程序。CrowdStrike提供的解决方案相当复杂,用户需要…

JavaFX布局-ScrollPane

JavaFX布局-ScrollPane 常用属性paddingcontentvbarPolicyhbarPolicyfitToWidthfitToHeight 实现方式Java实现 一个容器组件&#xff0c;用于展示那些可能超出窗口尺寸的内容当内容超过容器的大小时&#xff0c;会自动出现滚动条 常用属性 padding 内边距&#xff0c;可以单独…

【开源分享】PHP在线提交工单源码|工单管理系统源码 (附源码搭建教程)

一、设备报修工作内容 1.工单管理&#xff1a;设备报修系统可以将设备故障统计为工单并对工单进行汇总管理。将工单数据进行归类&#xff0c;将故障分类进行查看、统计、分析等等。 2.设备状态&#xff1a;工单可通过用户上报设备状态数据进行查看&#xff0c;维修工程师在维…

跟李沐学AI:LeNet

LeNet整体由两部分组成&#xff1a;由两个卷积层组成的卷积编码器、由三个全连接层组成的全连接层密集快。 每个卷积块的基本单元是一个卷积层、一个sigmoid激活函数和平均池化层。每个卷积层使用5x5的卷积核和一个sigmoid激活函数。 这些层将输入映射到多个二维特征输出同时输…

保研机试练习:leetcode算法top200(第二弹)

&#x1f32e;101.对称二叉树&#xff08;简单&#xff09; &#x1f35f;题目描述 &#x1f35f;题目反思 对称二叉树&#xff0c;对每个节点来说&#xff0c;就是当前节点相同&#xff0c;且左右镜像相等。这道题目重点也是在于掌握递归检查树上。 &#x1f35f;代码 /**…

C# 自定义控件无法加载

问题 在做winform开发时自己定义了一个控件&#xff0c;控件在工具箱中显示了&#xff0c;但是拖动到窗体设计器时会提示未能加载工具箱项xxx&#xff0c;将从工具箱中将其删除&#xff0c;如下图所示: 点击确定后&#xff0c;控件会从工具箱中移除。 解决方法 将 生成>…

深信服的云桌面操作简要

看了深信服的云桌面操作手册&#xff0c;讲真&#xff0c;我是没有耐心看的&#xff0c;656页&#xff0c;我是云桌面管理员&#xff0c;为了管理也必须耐着性子去看&#xff0c;但我看了40页就看不下去了&#xff0c;太啰嗦了。 深信服的技术人员安装好服务器后给我实际演示操…

【C++题解】1351. 买公园门票

欢迎关注本专栏《C从零基础到信奥赛入门级&#xff08;CSP-J&#xff09;》 问题&#xff1a;1351. 买公园门票 类型&#xff1a;简单穷举 题目描述&#xff1a; 某公园门票价格为&#xff1a;成人票 8 元 / 张&#xff0c;儿童票 3 元 / 张&#xff1b;某旅游团来公园游玩&…

Memcached未授权访问漏洞

Memcached未授权访问漏洞 Memcache能够提供临时数据存储服务&#xff0c;可以提高网站的整体性能&#xff0c;但由于memcache安全设计缺陷&#xff0c;默认开放的端口是11211&#xff0c;导致不需要密码就可以访问&#xff0c;攻击者可以直接连接服务器的11211端口获取数据库中…

GIt最新教程通俗易懂

Git学习笔记 一、Git版本控制分类1.1 本地版本控制1.2 集中版本1.3 分布式版本控制系统1.5 Git和SVN的区别二、Git的历史 三、Gti基础学习3.1 Git的基础学习3.2 启动Git 3.3 Git基本的配置3.3.1 配置文件相关位置 四、Git基本理论&#xff08;核心&#xff09;4.1 Git 的工作流…

vue echarts 柱状图和折线图的组合

柱状图和折线图的组合代码如下&#xff1a; <template><div><div id"barLineChart" ref"barLineChartRef" style"width: 100%; height: 450px"></div></div> </template><script> import * as echar…

【收录率高丨最快会后3-4个月EI检索 | 往届均已EI检索】第四届光学与通信技术国际学术会议(ICOCT 2024,8月9-11)

欢迎参加第四届光学与通信技术国际学术会议&#xff08;ICOCT 2024&#xff09;&#xff0c;该会议将于2024年8月9-11日在南京举办。自2021年首次会议以来&#xff0c;ICOCT已经发展成为光学和通信领域较有影响力的国际会议之一&#xff0c;聚焦最前沿的技术进展与未来发展趋势…

C/C++大雪纷飞代码(完整代码)

目录 写在前面 C语言简介 EasyX简介 大雪纷飞 运行结果 写在后面 写在前面 本期博主给大家带来了C/C++实现的大雪纷飞代码,一起来看看吧! 系列推荐 序号目录直达链接1爱心代码C/C++爱心代码(完整代码)_爱心代码编程c++语言-CSDN博客2李峋同款跳动的爱心C/C++李峋同…