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
时间: 2024-10-06 22:13:18

java设计模式之生产者/消费者模式的相关文章

设计模式之生产者消费者模式

一丶背景 说到生产者消费者模式就要先提提多线程了,多线程开发是开发中所常用的,多线程程序相对于单线程程序稳定性更强, 一个线程挂了不会影响整个程序的正常运行.但是当多线程同时操作一个数据源的时候就会出现脏读. 二丶介绍生产者消费者模式 生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题.生产者和消费者彼此之间不直接通讯,而通过 阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而 是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区

Java多线程-----实现生产者消费者模式的几种方式

   1 生产者消费者模式概述 生产者消费者模式就是通过一个容器来解决生产者和消费者的强耦合问题.生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理, 直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力.这个阻塞队列就是用来给生产者和消费者解耦的. 在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程.在多线程开发当中,如果生产者处理速度很快,而消费者处理速度

JAVA多线程之生产者消费者模式

一.什么是生产者消费者模式? 生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题.生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力. 二.为什么要使用生产者和消费者模式 在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程.在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产

Java多线程_生产者消费者模式1

生产者消费者模型       具体来讲,就是在一个系统中,存在生产者和消费者两种角色,他们通过内存缓冲区进行通信,生产者生产消费者需要的资料,消费者把资料做成产品.生产消费者模式如下图.(图片来自网络,侵删!) 生产者消费者模型的实现 生产者是一堆线程,消费者是另一堆线程,内存缓冲区可以使用List数组队列,数据类型只需要定义一个简单的类就好.关键是如何处理多线程之间的协作.这其实也是多线程通信的一个范例. 在这个模型中,最关键就是内存缓冲区为空的时候消费者必须等待,而内存缓冲区满的时候,生产者

生产者消费者模式(吃包子例子)

生产者-消费者问题是一个经典的进程同步问 题,该问题最早由Dijkstra提出,用以演示他提出的信号量机制.在同一个进程地址空间内执行的两个线程生产者线程生产物品,然后将物品放置在一个空 缓冲区中供消费者线程消费.消费者线程从缓冲区中获得物品,然后释放缓冲区.当生产者线程生产物品时,如果没有空缓冲区可用,那么生产者线程必须等待消费 者线程释放出一个空缓冲区.当消费者线程消费物品时,如果没有满的缓冲区,那么消费者线程将被阻塞,直到新的物品被生产出来. 生产者消费者模式是并发.多线程编程中经典的设计

聊聊并发——生产者消费者模式

在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题.该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度. 为什么要使用生产者和消费者模式 在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程.在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据.同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者.为了解决这个问题于是引入了生产者和消费者模式. 什么是生产者消费者模式 生产者

生产者消费者模式(1)

http://blog.csdn.net/kzq_qmi/article/details/46945753 生产者消费者问题(Producer-consumer problem)是一个多线程同步问题的经典案例.该问题描述了两个共享固定大小缓冲区的线程--即所谓的"生产者"和"消费者"--在实际运行时会发生的问题.生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程.与此同时,消费者也在缓冲区消耗这些数据.该问题的关键就是要保证生产者不会在缓冲区满时加入数据

Java并发程序设计(十一)设计模式与并发之生产者-消费者模式

设计模式与并发之生产者-消费者模式 生产者-消费者模式是一个经典的多线程设计模式.它为多线程间的协作提供了良好的解决方案.在生产者-消费者模式中,通常由两类线程,即若干个生产者线程和若干个消费者线程.生产者线程负责提交用户请求,消费者线程则负责具体处理生产者提交的任务.生产者和消费者之间则通过共享内存缓冲区进行通信.

Java的设计模式(7)— 生产者-消费者模式

生产者-消费者模式是一个经典的多线程设计模式,它为多线程间的协作提供了良好的解决方案.这个模式中,通常有两类线程,即若干个生产者线程和若干个消费者线程.生产者线程负责提交用户请求,消费者线程则负责具体处理生产者提交的任务.生产者和消费者之间通过共享内存缓存区进行通信,这样就避免了生产者和消费者直接通信,从而将生产者和消费者解耦.不管是生产高于消费,还是消费高于生产,缓存区的存在可以确保系统的正常运行.这个模式有以下几种角色: 生产者:用于提交用户的请求,提取用户任务,装入内存缓冲区. 消费者:在