互联网面试——生产者与消费者

生产者与消费者

背景

生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。解决生产者/消费者问题的方法可分为两类:

  • (1)采用某种机制保护生产者和消费者之间的同步;
  • (2)在生产者和消费者之间建立一个管道。第一种方式有较高的效率,并且易于实现,代码的可控制性较好,属于常用的模式。第二种管道缓冲区不易控制,被传输数据对象不易于封装等,实用性不强。因此本文只介绍同步机制实现的生产者/消费者问题。

实现方式

在Java中一共有四种方法支持同步,其中前三个是同步方法,一个是管道方法。

  1. wait() / notify()方法
  2. await() / signal()方法
  3. BlockingQueue阻塞队列方法
  4. PipedInputStream / PipedOutputStream

wait()/notify()
blockingQueue方式

public class ProducerConsumer<T> {
    static  class MsgQueueManager<T> {
        /**
         * 消息总队列
         */
        public final BlockingQueue<T> messageQueue;
        MsgQueueManager(BlockingQueue<T> messageQueue) {
            this.messageQueue = messageQueue;
        }
        MsgQueueManager() {
            this.messageQueue = new LinkedBlockingQueue<T>();
        }

        public void put(T msg) {
            try {
                messageQueue.put(msg);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }

        public T take() {
            try {
                return messageQueue.take();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            return null;
        }
    }

    static  class Producer extends Thread {
        private MsgQueueManager msgQueueManager;
        public Producer(MsgQueueManager msgQueueManager) {
            this.msgQueueManager = msgQueueManager;
        }
        @Override
        public void run() {
            msgQueueManager.put(new Object());
        }
    }
    static class Consumer extends Thread{
        private MsgQueueManager msgQueueManager;
        public Consumer(MsgQueueManager msgQueueManager) {
            this.msgQueueManager = msgQueueManager;
        }
        @Override
        public void run() {
            Object o = msgQueueManager.take();
        }
    }

    public static void main(String[] args) {
        MsgQueueManager<String> msgQueueManager = new MsgQueueManager<String>();

        for(int i = 0; i < 100; i ++) {
            new Producer(msgQueueManager).start();

        }
        for(int i = 0; i < 100; i ++) {
            new Consumer(msgQueueManager).start();

        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cool2Feel

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值