Producer Consumer 模式

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

一个简单的 UML 顺序图如下所示:

简单来说,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个整数,由于桌上只能放置一个整数,所以每生产一个就消耗一个。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值