首页 > 编程语言 >Java语言实现生产者与消费者的消息队列模型(附源码)

Java语言实现生产者与消费者的消息队列模型(附源码)

时间:2023-06-08 18:06:45浏览次数:64  
标签:Java 消费者 队列 list 生产者 源码 线程 消息


Java构建生产者与消费者之间的生产关系模型,可以理解生产者生产message,存放缓存的容器,同时消费者进行消费需求的消耗,如果做一个合理的比喻的话:

生产者消费者问题是线程模型中的经典问题。解决生产者/消费者问题有两种方法:一是采用某种机制保护生产者和消费者之间的同步;二是在生产者和消费者之间建立一个管道。第一种方式有较高的效率,并且易于实现,代码的可控制性较好,比较常用。生产者将消息提前生产好,存放在一个中间的区域(缓存),当消费者提出消费需求的时候进行,消息队列提供message及时提供与消费。

Java语言实现生产者与消费者的消息队列模型(附源码)_并发编程

使用消息队列(缓存)的好处有以下几个:
1.解耦(去依赖),如果是消费者直接调用生产者,那如果生产者的代码变动了,消费者的代码也需要随之变动。
2.高效,如果消费者直接掉生产者,执行时间较长的话,会阻塞,影响其他业务的进行
3.负载均衡,如果消费者直接调生产者,那生产者和消费者就得在一起了,日后业务量非常大的话,要想减轻服务器的压力,想拆分生产和消费,就很困难。

简单来说:消息队列就是实现了生产者与消费者之间的一个“中介”,避免了生产者与消费者的直接接触造成的麻烦,提高了生产与消耗的运转效率。

说到效率就要提到多线程,为了提高效率,因此多线程的消息队列的构建会涉及到Java的并发编程以及容器的读写配置。
好的已经进入了考点范围,那我们废话不多说,直接进入正题。
JAVA语言的消费者与生产模型包括以下的两个方面:

(1)指定容器的数量以及属性参数:

//LinkedList容器的最大容量为2
    public static final int MAX_SIZE = 2;
    //选定存储容器为LinkedList
    private static LinkedList<Integer> list = new LinkedList<>();

(2)指定生产者类对象(Producer)

static class Producer implements Runnable {
        @Override
        public void run() {
            synchronized (list) {
                //仓库容量已经达到最大值
                while (list.size() == MAX_SIZE) {
                    System.out.println("仓库已满,生产者" + Thread.currentThread().getName() + "不可生产.");
                    try {
                        list.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                list.add(1);
                System.out.println("生产者" + Thread.currentThread().getName() + "生产, 仓库容量为" + list.size());
                list.notify();
            }
        }
    }

在整个的生产者所生产的message消息中,设计多线程的数据读写,因此采用sychronized保证读写的线程安全。
备注:当线程读写的时候,消息队列发生存储满的情况,则输出队列已满,否则则将元素写入队列中去。

(3)消费者对象类(Consumer):

static class Consumer implements Runnable {

        @Override
        public void run() {
            synchronized (list) {
                while (list.size() == 0) {
                    System.out.println("仓库为空,消费者" + Thread.currentThread().getName() + "不可消费.");
                    try {
                        list.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                list.removeFirst();
                System.out.println("消费者" + Thread.currentThread().getName() + "消费,仓库容量为" + list.size());
                list.notify();
            }
        }
    }

消费者的对象的实现原理与生产者的实现原理相同,保证线程安全的线程同步机制也均为sychronized与wait
整个的消息队列的实现流程为:
(1)生产者将生产的message存放进消息队列,
(2)如果消息队列中的元素已满则停止消息的生产。
(3)当消费者提出消费请求的时候,如果消息队列为空,将锁释放,调用线程的wait接口,等待生产者生产。

编写测试用例输出如下:

Java语言实现生产者与消费者的消息队列模型(附源码)_并发编程_02


标签:Java,消费者,队列,list,生产者,源码,线程,消息
From: https://blog.51cto.com/u_13638291/6442031

相关文章

  • 一文读懂大厂面试的JAVA基础(集合,面向对象特性,反射,IO,容器)
    整理了操作系统,计算机网络,以及JVM的高频面试题目,对于面试大厂的Android以及后端开发岗位,可以说的是十分必要的部分就是JAVA语言的基础,在整体的内容上我认为有以下的几个部分,我发现任何的学习都是先建立框架体系,再逐个击破,针对Java的基础中包括:(1)Java语言的面向对象的特性(2)Java语言......
  • Java面试题查缺补漏习题,锁的升级,动态代理
    之前我们总结了Java面试题目中的关于计算机网络,操作系统,以及JVM虚拟机,以及Java的相关特性。今天又看了很多面试的视频,对面试的题目进行一下仔细的补充。1.对称加密与非对称加密的区别:非对称加密和对称加密在加密和解密过程、加密解密速度、传输的安全性上都有所不同,具体介绍如下:......
  • Java开发工程师学习日记(九)
    1.TCP与UDP网络传输协议方面:TCP的传输报文形式比UDP的传输形式更加复杂,因此UDP头部只有四个字段,因此传输效率比较,TCP<UDP2.数组或者字符串的null值含义:null表示字段或者变量还没有确定的值,3.IP地址的分类:A类:0.0.0.0~127.255.255.255B类:128.0.0.0~191.255.255.255C类:192.0.0.0~......
  • java 访问ingress https报错javax.net.ssl.SSLHandshakeException: Received fatal al
    一、报错及部署环境Java程序访问测试域名https方法正常,访问生产域名https域名报错,报错如下javax.net.ssl.SSLHandshakeException:Receivedfatalalert:protocol_version测试环境使用KubeSphereingress生产环境使用阿里云ACK服务的ingress配置二、问题原因客户端......
  • Java中枚举类的特殊用法-使用枚举实现单例模式和策略模式
    上面针对枚举类实现单例模式和策略模式有所涉及,下面补充。Java中使用枚举类实现单例模式为什么可以这样做?枚举类不能new,因此保证单例枚举类不能被继承类不加载时,不会实例化使用枚举类创建的单例还有一个好处,就是即使使用反射,也无法打破它的单例性质新建枚举类publicenumSingleEn......
  • Java基础之基础语法与面向对象
    前言小知识Java由Sun公司于1995年推出,2009年Sun公司被Oracle公司收购,取得Java的版权Java之父:JamesGosling(詹姆斯·高斯林) 专业术语JDK:javadevelopmentkit(java开发工具包)JRE:javaruntimeenvironment(java运行环境)JVM:javavirualma......
  • el-api包冲突,java.lang.LinkageError: loader constraints violated when linking ja
    java.lang.LinkageError:loaderconstraintsviolatedwhenlinkingjavax/el/ExpressionFactoryclass严重:Servlet.service()forservletjspthrewexceptionjava.lang.LinkageError:loaderconstraintsviolatedwhenlinkingjavax/el/ExpressionFactoryclassat......
  • java reflection Java 反射,动态绑定
    javareflection,java反射,动态绑定                                       Reflection是Java程序开发语言的特征之一,它允许运行中的Java程序对自身进行检查,或者说“自审”,并能直接操作程序的内部属性。例如,使用它能获得Java类中......
  • JSON与JAVA数据的转换
    JSON与JAVA数据的转换关键字:jsonjavaJSON-lib这个Java类包用于把bean,map和XML转换成JSON并能够把JSON转回成bean和DynaBean。下载地址:http://json-lib.sourceforge.net/还要需要的第3方包:jakartacommons-lang2.3jakartacommons-beanutils1.7.0j......
  • 前端进化笔记-JavaScript(三)
    人类在白色的底色上描绘图画,地球在黑色的底色上创造生命。变量、作用域与内存JavaScript的变量可以说是独树一帜。只需要一个(或两个等)关键字(const,let)就可以创建变量,创建时不考虑变量的类型,这是其他语言少有的强大功能。当然强大的功能总是伴随着问题。值原始值:Undefined,Null......