Java基础-多线程JUC-生产者和消费者

news2024/11/24 13:58:13

1. 生产者与消费者

在这里插入图片描述

实现线程轮流交替执行的结果;
实现线程休眠和唤醒均要使用到锁对象;
修改标注位(foodFlag);
代码实现:

public class demo11 {
    public static void main(String[] args) {
        /**
         * 需求:完成消费者和生产者(等待唤醒机制)的代码
         *      实现线程轮流交替执行的结果
         */
        Cooker cooker = new Cooker();
        Foodie foodie = new Foodie();

        cooker.setName("厨师");
        foodie.setName("吃货");

        cooker.start();
        foodie.start();
    }
}
class Cooker extends Thread {
    @Override
    public void run() {
        /**
         * 1.循环
         * 2.同步代码快
         * 3.判断共享数据是否到了末尾(到了末尾)
         * 4.判断共享数据是否到了末尾(没到末尾,执行核心逻辑)
         */
        while(true){
            synchronized (Desk.lock){
                if(Desk.count == 0){
                    break;
                }else {
                    // 判断桌子上是否有食物
                    if(Desk.foodFlag == 1) {
                        // 如果有,就等待
                        try {
                            Desk.lock.wait();
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }else {
                        // 如果没有,就制作食物
                        System.out.println("厨师在制作面条");
                        // 修改桌子上的食物状态
                        Desk.foodFlag = 1;
                        // 叫醒等待的消费者开吃
                        Desk.lock.notifyAll();
                    }
                }
            }
        }
    }
}
class Foodie extends Thread {
    @Override
    public void run() {
        /**
         * 1.循环
         * 2.同步代码快
         * 3.判断共享数据是否到了末尾(到了末尾)
         * 4.判断共享数据是否到了末尾(没到末尾,执行核心逻辑)
         */
        while(true){
            synchronized (Desk.lock) {
                if(Desk.count == 0){
                    break;
                }else {
                    // 先判断桌子上面是否有面条
                    if(Desk.foodFlag == 0) {
                        // 如果没有,就等待
                        // 不管是等待还是唤醒都是需要用锁对象进行处理的
                        try {
                            Desk.lock.wait(); // 让当前线程跟锁进行绑定
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }else {
                        // 把吃的总数-1
                        Desk.count --;
                        // 如果有,就开吃
                        System.out.println("吃货在吃面条,还能再吃 " + Desk.count + "碗!");
                        // 吃完之后,就唤醒厨师继续做
                        Desk.lock.notifyAll();
                        // 最后要修改桌子的状态
                        Desk.foodFlag = 0;
                    }
                }
            }
        }
    }
}

class Desk extends Thread {
    /**
     * 作用:控制生产者和消费者的执行
     */

    // 是否有面条 0:没有面条 1:有面条
    public static int foodFlag = 0;

    // 总个数
    public static int count = 10;

    // 锁对象
    public static Object lock = new Object();
}

2. 使用阻塞队列实现

阻塞队列,当存入数据时,如果空间已满就阻塞;当取出数据时,如果没有数据在队列中就阻塞;

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

public class demo12 {
    public static void main(String[] args) {
        /**
         * 需求:利用阻塞队列完成生产者和消费者
         * 细节:
         *      生产者和消费者必须使用同一个阻塞队列
         */
        //1. 创建阻塞队列的对象
        ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<String>(1);

        //2. 创建线程的对象,并把阻塞队列传递过去
        Cook12 cook12 = new Cook12(queue);
        Foodie12 foodie12 = new Foodie12(queue);

        cook12.start();
        foodie12.start();
    }
}
class Cook12 extends Thread {

    //只定义,不给值
    ArrayBlockingQueue<String> queue;

    //让构造方法获取
    public Cook12(ArrayBlockingQueue<String> queue) {
        this.queue = queue;
    }

    @Override
    public void run() {
        while(true){
            //不断的把面条放到阻塞队列之中
            try {
                //ctrl+b进入源码
                //put底层已经实现了锁,所以无需再写锁
                queue.put("面条");
                System.out.println("厨师做了面条");
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

class Foodie12 extends Thread {
    ArrayBlockingQueue<String> queue;

    //让构造方法获取
    public Foodie12(ArrayBlockingQueue<String> queue) {
        this.queue = queue;
    }
    @Override
    public void run() {
        while(true){
            //不断的从阻塞队列中获取面条
            try {
                //ctrl+b进入源码
                //put底层已经实现了锁,所以无需再写锁
                String take = queue.take();
                System.out.println(take);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

3. 多线程的6种状态

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

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

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

相关文章

java jvm TLAB是什么?指针碰撞解释,空闲列表解释

1. 对象的创建&#xff1a; 当Java虚拟机遇到一条字节码new指令时&#xff0c;首先将去检查这个指令的参数是否能在常量池中定位到 一个类的符号引用&#xff0c;并且检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有&#xff0c;那必须先执行相应的类加载过程…

SpringBoot 实现审核功能

一、审核功能实现的方式 1、普通 方案&#xff1a;经办时入A表&#xff0c;审核后从A表读取数据&#xff0c;然后操作目标B表&#xff1b; 优势&#xff1a;思路简单 劣势&#xff1a;对后端功能实行高度的嵌入&#xff1b;审核功能数据操作不统一 2、弹框式 方案&#x…

HummerRisk 配置 HTTPS访问

简介 HummerRisk 是开源的云原生安全平台&#xff0c;以非侵入的方式解决云原生的安全和治理问题。核心能力包括混合云的安全治理和云原生安全检测。 HTTPS&#xff08;Hypertext Transfer Protocol Secure&#xff09;是一种通过加密和身份验证来保护网络通信安全的协议。它…

ChatGPT对高等教育的可能影响与对策建议

ChatGPT来袭&#xff0c;将对高等教育带来哪些影响&#xff0c;我们又该如何应对&#xff1f; 对于ChatGPT&#xff0c;有人欢喜有人忧&#xff0c;不同人、不同领域评价不一。在一些人眼里&#xff0c;它就是天使&#xff0c;而在另外一些人眼里&#xff0c;它几乎可以说是魔…

php导出pdf

插件官网&#xff1a;TCPDF 博主用的是tp6框架 、tcpdf插件 composer require tecnickcom/tcpdf --ignore-platform-reqs 后面是忽略平台要求的参数 ---------------中文乱码start------------------ 关于中文乱码问题&#xff1a; 网上说的下载字体放入fonts 利用tools…

Linux之系统管理

系统管理 Linux中的进程和服务 计算机中&#xff0c;一个正在执行的程序或命令&#xff0c;被叫做“进程”&#xff08;process&#xff09;。 启动之后一直存在、常驻内存的进程&#xff0c;一般被称作“服务”&#xff08;service&#xff09; service 服务管理&#xff…

GaussDB OLTP云数据库配套工具DDM

目录 一、前言 二、DDM定义 三、DDM业务架构 四、为什么需要DDM? 五、DDM特性 六、DDM应用场景 一、前言 现在越来越多的企业应用在逐步向云平台迁移&#xff0c;同时这对云平台带了一个严峻的考验和挑战。但针对华为云GaussDB数据库&#xff0c; 我们在生态方面做了比…

利用iptables + zabbix-agent 监控进程端口流量

这几天部署了一台ARM架构的linux系统的监控&#xff0c;服务器系统上没有任何工具可以获取数据来获取端口流量&#xff0c;yum&#xff0c;apt-get软件包管理工具都没有&#xff0c;所以想获取数据比较困难。 最终决定使用iptables来添加几条指定端口的规则来统计入站流量和出站…

电子时钟制作(瑞萨RA)(7)----按键修改数码管时间

概述 前几节课程已经单独驱动了数码管和RTC&#xff0c;同时已经整合成了能够用数码管显示具体时间&#xff0c;但是无法修改时间&#xff0c;这节就来配置使用按键修改具体的日期。 硬件准备 首先需要准备一个开发板&#xff0c;这里我准备的是芯片型号R7FA2E1A72DFL的开发…

【花雕】全国青少年机器人技术一级考试备考实操搭建手册9

随着科技的不断进步&#xff0c;机器人技术已经成为了一个重要的领域。在这个领域中&#xff0c;机械结构是机器人设计中至关重要的一部分&#xff0c;它决定了机器人的形态、运动方式和工作效率。对于青少年机器人爱好者来说&#xff0c;了解机械结构的基础知识&#xff0c;掌…

记录Maven 依赖包版本号奇奇怪怪的问题 - okhttp3、okio 版本指定无效

问题背景 SprintBoot项目使用Okhttp 封装SDK common-http&#xff0c;根据官网使用Maven导入JavaSDK <dependency><groupId>io.github.admin4j</groupId><artifactId>http</artifactId><version>0.7.4</version> </dependency&…

Vue 数据双向绑定

双向数据绑定 : 通过前面学习知道 Vue 是数据驱动的&#xff0c;数据驱动有一个精髓之处是数据双向绑定&#xff0c; 即当数据发生变化的时候&#xff0c;视图也就发生变化&#xff0c;当视图发生变化的时候&#xff0c;数据也会跟着同步变化。&#xff08;就是mvvm数据发生变化…

MyCat2 使用教程(一)初始安装

MyCat2 使用教程&#xff08;一&#xff09;初始安装 Mycat2是Mycat社区开发的一款分布式关系型数据库&#xff08;中间件&#xff09;。它支持分布式SQL查询&#xff0c;兼容MySQL通信协议&#xff0c;以Java生态支持多种后端数据&#xff0c;通过数据分片提高数据查询处理能…

【C++】5.多线程:ThreadPoll线程池实现

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍ThreadPoll线程池实现。 学其所用&#xff0c;用其所学。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;下次更新不迷路…

Web3.0 在中国市场的规模如何?其特点有什么?

随着区块链技术的不断发展和普及&#xff0c;Web3.0 作为下一代互联网的发展趋势&#xff0c;在中国市场也逐渐受到了关注和应用。那么&#xff0c;Web3.0 在中国市场的规模如何&#xff1f;其特点又有哪些呢&#xff1f; 首先&#xff0c;让我们来看一下 Web3.0 在中国市场的规…

Python3,Pandas这4种高频使用的筛选数据的方法,不得不说,确实挺好。

Pandas数据筛选方法 1、引言2、4种高频使用数据筛选方法2.1 布尔索引2.2 isin()方法2.3 query()方法2.4 loc[]方法 3、总结 1、引言 小屌丝&#xff1a;鱼哥&#xff0c;share一下 数据筛选的方法呗 小鱼&#xff1a;Excel就可以啊 小屌丝&#xff1a;我要用Pandas 小鱼&#…

0073. 矩阵置零

73. 矩阵置零 原题链接&#xff1a;完成情况&#xff1a;解题思路&#xff1a;解法一&#xff1a;构造一个同等规模的二维数组&#xff0c;即所谓的m*n解法二&#xff1a; int row[] new int[m]; int col[] new int[n];解法三&#xff1a;常数量级 参考代码&#xff1a; 原题…

软件测试技能,JMeter压力测试教程,请求头部自动签名带上X-sign参数(二十二)

一、前言 接口请求 body 带有 sign 签名参数&#xff0c;sign 签名是根据请求 body 除去 sign 本身参数后&#xff0c;拼接请求参数最后 md5 加密生成的 前面一篇是把 sign 前面参数放到请求的 body 里面&#xff0c;这篇继续讲把签名参数放到请求头部的情况 二、实现方式 …