java设计模式之生产者/消费者模式
什么是生产者/消费者模式?
某个模块负责产生数据,这些数据由另一个模块来负责处理(此处的模块是广义的,可以是类、函数、线程、进程等)。产生数据的模块,就形象地称为生产者;而处理数据的模块,就称为消费者。在生产者与消费者之间在加个缓冲区,我们形象的称之为仓库,生产者负责往仓库了进商品,而消费者负责从仓库里拿商品,这就构成了生产者消费者模式。结构图如下:

生产者消费者模式有如下几个优点:
1、解耦
由于有缓冲区的存在,生产者和消费者之间不直接依赖,耦合度降低。
2、支持并发
由于生产者与消费者是两个独立的并发体,他们之间是用缓冲区作为桥梁连接,生产者只需要往缓冲区里丢数据,就可以继续生产下一个数据,而消费者只需要从缓冲区了拿数据即可,这样就不会因为彼此的处理速度而发生阻塞。
3、支持忙闲不均
缓冲区还有另一个好处。如果制造数据的速度时快时慢,缓冲区的好处就体现出来 了。当数据制造快的时候,消费者来不及处理,未处理的数据可以暂时存在缓冲区中。 等生产者的制造速度慢下来,消费者再慢慢处理掉。
生产者-消费者模型准确说应该是“生产者-仓储-消费者”模型,这样的模型遵循如下的规则:
1、生产者仅仅在仓储未满时候生产,仓满则停止生产。
2、消费者仅仅在仓储有产品时候才能消费,仓空则等待。
3、当消费者发现仓储没产品可消费时候会通知生产者生产。
4、生产者在生产出可消费产品时候,应该通知等待的消费者去消费
此模型将要结合java.lang.Object的wait与notify、notifyAll方法来实现以上的需求。实例代码如下:
创建所谓的“仓库”,此类是(本质上:共同访问的)共享数据区域
//此类是(本质上:共同访问的)共享数据区域
public class SyncStack { private String[] str = new String[10]; private int index; //供生产者调用
public synchronized void push(String sst){
if(index == sst.length()){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
this.notify();//唤醒在此对象监视器上等待的单个线程
str[index] = sst;
index++;
} //供消费者调用
public synchronized String pop(){
if(index == 0){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
this.notify();
index--;
String product = str[index];
return product; } //就是定义一个返回值为数组的方法,返回的是一个String[]引用
public String[] pro(){
return str;
}
}
创建生产者:
public class Producter implements Runnable {
private SyncStack stack;
public Producter(SyncStack stack){
this.stack = stack;
}
public void run(){
for(int i = 0;i<stack.pro().length;i++){
String producter = "产品" + i;
stack.push(producter);
System.out.println("生产了:" + producter);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
创建消费者:
public class Consumer implements Runnable {
private SyncStack stack;
public Consumer(SyncStack stack){
this.stack = stack;
}
public void run(){
for(int i=0;i<stack.pro().length;i++){
String consumer = stack.pop();
System.out.println("消费了:" + consumer );
try {
Thread.sleep(400);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
测试类:
public class TestDeam {
public static void main(String[] args) {
SyncStack stack = new SyncStack();
Consumer p = new Consumer(stack);
Producter c = new Producter(stack);
new Thread(p).start();
new Thread(c).start();
}
}
测试结果:
生产了:产品0
消费了:产品0
生产了:产品1
生产了:产品2
消费了:产品2
生产了:产品3
消费了:产品3
生产了:产品4
生产了:产品5
生产了:产品6
消费了:产品5
生产了:产品7
消费了:产品6
消费了:产品7
生产了:产品8
生产了:产品9
消费了:产品8
消费了:产品9
消费了:产品4
消费了:产品1
java设计模式之生产者/消费者模式的更多相关文章
- Java设计模式之生产者消费者模式
Java设计模式之生产者消费者模式 博客分类: 设计模式 设计模式Java多线程编程thread 转载 对于多线程程序来说,不管任何编程语言,生产者和消费者模型都是最经典的.就像学习每一门编程语言一 ...
- java+反射+多线程+生产者消费者模式+读取xml(SAX)入数据库mysql-【费元星Q9715234】
java+反射+多线程+生产者消费者模式+读取xml(SAX)入数据库mysql-[费元星Q9715234] 说明如下,不懂的问题直接我[费元星Q9715234] 1.反射的意义在于不将xml tag ...
- Java多线程-----实现生产者消费者模式的几种方式
1 生产者消费者模式概述 生产者消费者模式就是通过一个容器来解决生产者和消费者的强耦合问题.生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理 ...
- 【多线程】java多线程实现生产者消费者模式
思考问题: 1.为什么用wait()+notify()实现生产者消费者模式? wait()方法可以暂停线程,并释放对象锁 notify()方法可以唤醒需要该对象锁的其他线程,并在执行完后续步骤,到了s ...
- Java实现多线程生产者消费者模式的两种方法
生产者消费者模式:生产者和消费者在同一时间段内共用同一存储空间,生产者向空间里生产数据,而消费者取走数据.生产者生产一个,消费者消费一个,不断循环. 第一种实现方法,用BlockingQueue阻塞队 ...
- Java多线程_生产者消费者模式2
在我的上一条博客中,已经介绍到了多线程的经典案列——生产者消费者模式,但是在上篇中用的是传统的麻烦的非阻塞队列实现的.在这篇博客中我将介绍另一种方式就是:用阻塞队列完成生产者消费者模式,可以使用多种阻 ...
- Java 并发编程 生产者消费者模式
本文部分摘自<Java 并发编程的艺术> 模式概述 在线程的世界里,生产者就是生产数据的线程,消费者就是消费数据的数据.生产者和消费者彼此之间不直接通信,而是通过阻塞队列进行通信,所以生产 ...
- Java多线程编程——生产者-消费者模式(1)
生产者-消费者模式在生活中非常常见.就拿我们去餐馆吃饭为例.我们会遇到以下两种情况: 1.厨师-客人 如下图所示,生产者.消费者直接进行交互. 生产者生产出产品后,通知消费者:消费者消费后,通知生产者 ...
- JAVA多线程之生产者 消费者模式 妈妈做面包案例
创建四个类 1.面包类 锅里只可以放10个面包 ---装面包的容器2.厨房 kitchen 生产面包 和消费面包 最多生产100个面包3.生产者4消费者5.测试类 多线程经典案例 import ja ...
随机推荐
- .psl脚本介绍
.ps1文件是PowerShell写好的脚本文件 可以在记事本中写一段PowerShell代码,然后将其保存为“xxx.ps1”,后面要使用它的时候,双击即可运行了.这有点像批处理的“.bat”文件, ...
- python 协程 demo
# -*- coding: UTF- -*- import gevent from gevent import socket from gevent import event rev=socket.s ...
- img 下方的4px像素问题
问题:在一个div块里面放了一个图片,图片下面有内容,可以不管怎么调试,在火狐浏览器,IE6下.图片img底部多出了4个像素 解决:img样式中 vertical-align: top/middl ...
- 结合CRT与欧拉定理高阶幂求余
- 总要先爬出坑的JEE架构
先来看看官网对它的定义. Java平台企业版(Java EE)是社区驱动的企业软件的标准.Java EE是使用Java Community Process开发的,其中包括来自行业专家,商业和开源组织, ...
- 学习笔记7—python 列表,数组,矩阵两两转换tolist()
from numpy import * a1 =[[1,2,3],[4,5,6]] #列表 print('a1 :',a1) #('a1 :', [[1, 2, 3], [4, 5, 6]]) ...
- AtCoder Regular Contest 102 D - All Your Paths are Different Lengths
D - All Your Paths are Different Lengths 思路: 二进制构造 首先找到最大的t,使得2^t <= l 然后我们就能构造一种方法使得正好存在 0 到 2^t ...
- Asp.net core 学习笔记 ( Router 路由 )
和之前的一样用法. public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory log ...
- java调用dll/so文件
大家都知道用C++编写的程序如果用于windows使用则编译为xxx.dll文件,如果是Linux使用则编译为libxxx.so文件.下面将java调用dll/so文件的方法粘出来方便下次使用.此处使 ...
- [Spring] Aspect Oriented Programming with Spring | AOP | 切面 | 切点
使用Spring面向切面编程 1.介绍 AOP是OOP的补充,提供了另一种关于程序结构的思路. OOP的模块化的关键单位是 类 . AOP的则是aspect切面. AOP 将程序的逻辑分成独立的块(叫 ...