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()); } } } }