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

  • Post author:
  • Post category:java


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

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

在这里插入图片描述

使用消息队列(缓存)的好处有以下几个:

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接口,等待生产者生产。

编写测试用例输出如下:

在这里插入图片描述

完整的代码欢迎关注我的微信公众号:千与编程

回复“生产消费”,领取全部源代码,

回复“微信”,加我微信,交流技术哦~

在这里插入图片描述
致谢:

https://www.cnblogs.com/geoffreygao/p/11929362.html



版权声明:本文为baidu_39629638原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。