Himalayas

博客园 首页 联系 订阅 管理

1. 为什么使用生产者消费者模式

(1)解耦合。消费者只关心队列里面取出来的数据,不用关心数据的来源。比如,生产者服务的域名,url这些变更。

(2)支持异步。生产者生产出来数据,直接放入队列就好了,接着生产下一个数据,不必等待。比如厨师做菜的时候,只需要把做好的菜放到传送带就接着做下一道菜。不需要有等有顾客过来把这个菜领走在做下一道;效率更高。

(3)流量削峰。双十一零点那一刻,qps会飙升。如果为了这一小会的时间,增加机器不划算,因为平时的时候,这些机器足够用。那我可以吧这些请求放到一个队列,服务从队列中拿出请求,运算后返回给客户端。

 

2. 生产者消费者图示

 

 

3. 代码实现

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;

public class ProducerConsumer<E> {
    private int queueSize = 5;
    private int producerNum = 2;
    private int consumerNum = 2;
    //创建一个阻塞队列
    private LinkedBlockingQueue<E> blockingQueue = null;
    //生产者线程池
    private ExecutorService producerTheadPool = null;
    //消费者线程池
    private ExecutorService consumerTheadPool = null;

    public ProducerConsumer(){
        blockingQueue = new LinkedBlockingQueue<>(queueSize);
        producerTheadPool = Executors.newFixedThreadPool(producerNum);
        consumerTheadPool = Executors.newFixedThreadPool(consumerNum);
    }

    public ProducerConsumer(int queueSize, int producerNum, int consumerNum){
        blockingQueue = new LinkedBlockingQueue<>(queueSize);
        producerTheadPool = Executors.newFixedThreadPool(producerNum);
        consumerTheadPool = Executors.newFixedThreadPool(consumerNum);
    }

    public void produceEleAsync(E ele){
        if(!checkSuccess()){
            return;
        }
        Producer<E> producer = new Producer<E>(this.blockingQueue, ele);
        producerTheadPool.execute(producer);
    }

    //执行消费过程
    public void consumeEleAsync() {
        if(!checkSuccess()){
            return;
        }
        new Thread(new Runnable() {
            @Override
            public void run() {
                while(true){
                    try {
                        E ele = blockingQueue.take();//阻塞获取数据
                        Consumer<E> consumer = new Consumer<E>(ele);
                        consumerTheadPool.execute(consumer);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }

    //判空检查
    private boolean checkSuccess(){
        if(blockingQueue!=null
                && producerTheadPool!=null
                && consumerTheadPool!=null){
            return true;
        }
        return false;
    }

    //生产者
    private class Producer<E> implements Runnable{
        private LinkedBlockingQueue<E> blockingQueue;
        private E ele;

        public Producer(LinkedBlockingQueue<E> blockingQueue, E ele){
            this.blockingQueue = blockingQueue;
            this.ele = ele;
        }

        @Override
        public void run() {
            if(this.blockingQueue!=null && ele!=null){
                try {
                    this.blockingQueue.put(ele);
                } catch (InterruptedException e) {
                    e.getStackTrace();
                }
            }
        }
    }

    //消费者
    private class Consumer<E> implements Runnable{
        private E ele;

        public Consumer(E ele){
            this.ele = ele;
        }

        @Override
        public void run() {
            //执行消费过程
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            if(ele!=null){
                System.out.println("消费--->" + ele.toString());
            }
        }
    }
    

}

 

posted on 2019-10-23 10:01  Himalayas  阅读(2026)  评论(0编辑  收藏  举报