`

Design Pattern: Producer Consumer 模式

阅读更多

Producer Consumer模式与 Guarded Suspension 模式 是类似的,只不过Guarded Suspension模式并不限制缓冲区的长度,Producer Consumer模式假设所生产的产品放置在一个长度有限制的缓冲区(就像是一个产品桌,它可以摆放的空间是有限的),如果缓冲区满了,则生产者必须停止继续将产品放到缓冲区中,直到消费者取走了产品而有了空间,而如果缓冲区中没有产品,当然消费者必须等待,直到有新的产品放到缓冲区中。

简单来说,Producer Consumer模式就像是加上了双重防护与等待的Guarded Suspension模式,而它的两个防护与等待的条件洽好相反,一个用Java实现的简单流程架构如下:
  • ProductTable.java
import java.util.LinkedList;

public class ProductTable {
    private LinkedList products = new LinkedList();

    public synchronized void addProduct(Product product) {
        while(products.size() >= 2) { // 容量限制为 2
            try {
                wait();
            }
            catch(InterruptedException e) {}
        }

        products.addLast(product);
        notifyAll();
    }
   
    public synchronized Product getProduct() {
        while(products.size() <= 0) {
            try {
                wait();
            }
            catch(InterruptedException e) {}
        }

        Product product = (Product) products.removeFirst();
        notifyAll();
     
        return product;
    }
} 


以下举一个最简单的:生产者每次生产一个整数并放置在桌子上,而消费者消耗整数,桌子上一次只能放置一个整数,如果桌子上已有整数,则生产者等待消费者将整数消耗并通知生产者生产下一个整数,如果桌子上没有整数,则消费者等待生产者生产整数并通知消费者可以消耗整数。

  • Producer.java
public class Producer extends Thread {
    private ProductTable productTable;
   
    public Producer(ProductTable productTable) {
        this.productTable = productTable;
    }
   
    public void run() {
        System.out.println("Produce integer......");
        for(int product = 1; product <= 10; product++) {
            try {
                // wait for a random time
                Thread.sleep((int) Math.random() * 3000);
            }
            catch(InterruptedException e) {
                e.printStackTrace();
            }
            productTable.setIntProduct(product);
        }      
    }
} 

 

  • Consumer.java
public class Consumer extends Thread {
    private ProductTable productTable;
   
    public Consumer(ProductTable productTable) {
        this.productTable = productTable;
    }
   
    public void run() {
        for(int i = 1; i <= 10; i++) {
            try {
                // wait for a random time
                Thread.sleep((int) (Math.random() * 3000));
            }
            catch(InterruptedException e) {
                e.printStackTrace();
            }
            productTable.getProductInt();
        }
    }
} 

 

生产者将产品放至桌上,而消费者将产品从桌上取走,所以桌子是个维护是否让被放置或消耗产品的地方,由它来决定谁必须等待与通知:

  • ProductTable.java
public class ProductTable {
    private int productInt = -1; // -1 for no product

    public synchronized void setIntProduct(int product) {
        if(productInt != -1) {
            try {
                wait();
            }
            catch(InterruptedException e) {
                e.printStackTrace();
            }
        }

        productInt = product;
        System.out.println("set (" + product + ")");
        notify();
    }
   
    public synchronized int getProductInt() {
        if(productInt == -1) {
            try {
                wait();
            }
            catch(InterruptedException e) {
                e.printStackTrace();
            }
        }

        int p = productInt;
        System.out.println("Get (" + productInt + ")");
        productInt = -1;
              
        notify();
      
        return p;
    }
} 


生产者会生产10个整数,而消费者会消耗10个整数,由于桌上只能放置一个整数,所以每生产一个就消耗一个。

分享到:
评论

相关推荐

    操作系统实验模拟生产者消费者问题

    PROGRAM NAME: PRODUCER_CONSUMER */ /* This program simulates two processes, producer which */ /* continues to produce message and put it into a buffer */ /* [implemented by PIPE], and consumer which ...

    example_posix:ProducerConsumer 问题使用(POSIX 信号量和线程)

    生产者/消费者问题使用(POSIX 信号量和线程) 获取文件: 在实验室计算机上,使用以下命令: ...课程: 创建和管理 POSIX 线程和信号量。 从多个 POSIX 线程访问共享(进程内)内存。 美味的早餐麦片... ...

    ProducerConsumer(生产者消费者问题的单线程模拟)

    std::thread consumerThread(consumer, std::ref(sharedQueue), std::ref(mutex), std::ref(cv)); producerThread.join(); consumerThread.join(); return 0; } ``` 在这个例子中,生产者和消费者通过互斥量和...

    Producer/Consumer 多线程处理文件

    在这个"Producer/Consumer 多线程处理文件"的主题中,我们将深入探讨Java中的生产者消费者模型,以及如何利用这一模式来高效地处理大量数据,如一秒钟处理一千多条记录。 生产者消费者模型源于操作系统理论,是解决...

    ProducerConsumer-CSharp:C# 制作的 ProducerConsumer Demo

    ProducerConsumer 模型是计算机科学中的一个经典设计模式,它主要解决了多线程环境下的资源同步和通信问题。在 C# 中,我们可以利用 .NET Framework 提供的并发和线程管理工具来实现这个模型。本项目 "Producer...

    example_sys5:ProducerConsumer 问题使用(System V 信号量共享内存)和进程

    使用(System V 信号量)和进程的生产者/消费者问题 获取文件: 在实验室计算机上,使用以下命令: git clone git://github....课程: 创建、管理和删除信号量组 创建、管理和删除共享内存段 美味的早餐麦片...

    full-stack-challenge:ProducerConsumer系统,生产者生成一个随机方程供消费者求解

    运行npm run consumer 在现代浏览器中访问 消费者运行后,您可以在现代浏览器中访问并获得表达式界面。 在评估来自任何生产者的表达式以及无法评估表达式时,此页面将自动更新。 该界面提供了一个输入,因此您...

    Flex基于Producer和Consumer方式的简易消息推送机制

    示例代码中使用的`mx:Application`、`mx:Script`、`mx:Producer`、`mx:Consumer`等都是Flex MX组件,它们是Adobe Flex框架的一部分,用于构建富互联网应用程序(RIA)。 通过以上知识点,我们可以理解Flex如何实现...

    用Java实现23种设计模式

    用Java实现23种设计模式 1. 创建型模式 工厂模式(Factory Pattern) 抽象工厂模式(Abstract Factory Pattern) 单例模式(Singleton Pattern) ... 生产者消费者模式(Producer Consumer Pattern)

    ProducerConsumer.java

    The use of producer-consumer questions helps to better understand threads.

    producer-customer.c文件

    利用信号量实现的多线程之间的同步与互斥,详情看博客文章Linux多线程编程(二)---线程之间的同步与互斥进阶实验

    57119101_王晨阳_ProducerConsumer1

    【Producer-Consumer问题】是经典的多线程同步问题,它涉及到如何在多个生产者和消费者之间共享有限资源的问题。在这个实验中,57119101_王晨阳_ProducerConsumer1通过Win32 API和Pthreads两种方式实现了这一问题的...

    consumer_producer_operatingsystems_producerconsumer_

    1、n个缓冲区的缓冲池作为一个临界资源:当生产者任务从数据源—文件中读取数据后将会申请一个缓冲区,并将此数据放缓冲区中。消费者任务从一个缓冲区中取走数据,并将其中的内容打印输出。当一个生产者任务正在访问...

    良葛格DesignPattern学习笔记

    良葛格的《Design Pattern学习笔记》不仅涵盖了经典的GOF设计模式,还额外介绍了几种多线程模式,这使得这份学习笔记成为了一个宝贵的学习资源。下面将对其中的部分设计模式进行详细介绍。 #### 二、GOF设计模式 ...

    ProducerConsumer:使用java实现经典的并发或线程模式

    2. **`Producer`和`Consumer`接口**:虽然Java标准库中没有现成的`Producer`和`Consumer`接口,但在设计模式中,我们通常定义这两个接口来表示生成数据和消耗数据的行为。实现这些接口的类将分别代表生产者和消费者...

    Python-kafka集群搭建PythonAPI调用Producer和Consumer

    在本教程中,我们将探讨如何搭建一个支持SASL(Simple Authentication and Security Layer)认证的Kafka集群,并使用Python API来创建Producer和Consumer。 ### 1. 安装Kafka 首先,我们需要在服务器上安装...

    producer_consumer_v2.c

    别人的太贵了,自己写一份分享!c语言实现生产者消费者模型,支持设置生产者消费者线程数量,支持设置消息数量。消息的组织形式为链表。生产者生产消息和消费者处理消息分别需要对应的条件变量。...

    ProducerConsumer.rar

    生产者消费者代码

    producer-consumer问题的分析和讨论

    3. `Producer.java`: 这个文件可能包含了生产者线程的实现。生产者线程会不断地生成数据(在这种情况下可能是事件对象),然后调用`EventStorage`的`put()`方法将数据放入队列。为了防止无限制地生成数据导致队列...

    Kafka客户端producer/consumer样例

    Kafka客户端producer/consumer样例

Global site tag (gtag.js) - Google Analytics