Java"设计模式"——生产消费者模式及三种实现方式
虽然生产消费者模型不算是Java的23种设计模式之一,但还是将其归为半个"设计模式"(属于我的设计模式)
一、生产消费者模式原理
1、生产消费者模式主要是将生产者与消费者解耦,通过一个容器来解决生产者和消费者的强耦合问题,生产者消费者彼此之间不直接通讯,而是通过阻塞队列来进行通讯。
2、生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者也不找生产者要数据,而是直接从阻塞队列中取得,阻塞队列相当于一个缓冲区
,平衡了生产者与消费者的处理能力,使得生产者与消费者是两个完全独立的并发主体。
3、生产者消费者的关系如下
①生产速度与消费速度的关系
a)生产速度>消费速度:存货
b)生产速度=消费速度:零库存(最理想)
c)生产速度<消费速度:缺货
②容器的容量要有限制,否则会有存货积压
a) 容器已满,停止生产,通知消费者消费(生产快于消费),生产者等待消费者消费。
b) 容器已空,停止消费,通知生产者生产(消费快于生产),消费者等待生产者生产
4、生产消费者模型应用
①生产消费者模型应用
a) 生产者与消费者速率不匹配问题(A产生数据,B消费数据,且速率不同)
b) 解耦,生产者与消费者相互之间没有关系(很多东西都能做容器)
②生产消费者实际开发问题
调整生产速度(休眠时间)以及生产者与消费者的个数用来控制生产消费模式(休眠时间基本实际开发中不会使用,实际开发中需要进行测试,得到生产者与消费者的速度差异,根据快慢情况决定生产者消费者的线程数,实现生产速度约等于消费速度)
二、生产消费者模式的多种实现
共3种实现
等待唤醒机制
等待唤醒+阻塞队列机制
Condition机制(内置等待唤醒+阻塞队列)
1、等待唤醒机制
概述:在商品类中设置两个synchronized方法,一个是生产商品方法(由生产者调用),另一个是消费商品方法(由消费者调用),当商品数为最大值时,停止生产,让消费者消费,当商品数为0时,停止消费,让生产者生产。
特点:生产者与消费者耦合度还是太高(两者只是通过一个商品类来交互)
package com.xiaoaxiao.test.thread_test.production_consumer_model;
import java.util.ArrayList;
import java.util.List;
/**
* Created by xiaoaxiao on 2019/7/15
* Description: 多线程的生产消费模式
*/
class Goods1{
private String goodsName;
private int count;
private int maxCount;
public Goods1(int maxCount) {
this.maxCount = maxCount;
}
// 生产商品方法
public synchronized void set(String goodsName){
while (this.count==maxCount){
try {
// 等待消费者消费
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.goodsName = goodsName;