zoukankan      html  css  js  c++  java
  • Java中设计模式之生产者消费者模式-4

    引言

    生产者-消费者(producer-consumer)问题,也称作有界缓冲区(bounded-buffer)问题,两个进程共享一个公共的固定大小的缓冲区。其中一个是生产者,用于将消息放入缓冲区;另外一个是消费者,用于从缓冲区中取出消息。问题出现在当缓冲区已经满了,而此时生产者还想向其中放入一个新的数据项的情形,其解决方法是让生产者此时进行休眠,等待消费者从缓冲区中取走了一个或者多个数据后再去唤醒它。同样地,当缓冲区已经空了,而消费者还想去取消息,此时也可以让消费者进行休眠,等待生产者放入一个或者多个数据时再唤醒它。

    生产者消费者模型

    四个类

    1.产品类:面包,饮料等
    2.资源类(中介类):超市(买卖各种产品)
    3.生产类(工厂类):生产各种产品
    4.消费者类(顾客类):消费各种产品

    代码:

    1.产品类

    package 设计模式之生产者消费者模式;
    
    public class Bread {
        private String brand;
        private double price;
        public String getBrand() {
            return brand;
        }
        public void setBrand(String brand) {
            this.brand = brand;
        }
        public double getPrice() {
            return price;
        }
        public void setPrice(double price) {
            this.price = price;
        }
        @Override
        public String toString() {
            return "Bread [brand=" + brand + ", price=" + price + "]";
        }
        public Bread(String brand, double price) {
            super();
            this.brand = brand;
            this.price = price;
        }
        public Bread() {
            super();
        }
    
    }
    

    2.中介类(资源类):超市

    负责统筹安排所有资源,是生产者和消费者的桥梁。类似多线程中的共享资源,各个线程来操作同一个资源。

    package 设计模式之生产者消费者模式;
    
    public class Market {
    //假设超市买面包的容量为6(即面包货架容量为6)
        private Bread[] breads=new Bread[6];
        int index=-1;// 为什么不默认为0  因为数组下标为0 是有一个数据的
        //从工厂进面包
        public synchronized void getBread(Bread bread){
            //如果昨天生意不好,没有卖出面包,此时就不需要进货
            if(index>=5){// 下标如果大于等于5 那就是有6个面包  工厂不需要生产  所以让工厂等着
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            //生意很好,卖出了面包,需要进货
            // 为了不覆盖任何面包   需要先加 下标 后赋值
            index++;
            //将进的面包放进数组里(货架上)
            breads[index]=bread;
            System.out.println("进了"+breads[index]);
            //进货后,(通知)让顾客消费
            this.notify();
        }
        // 卖面包
        public synchronized void saleBread(){
            //如果昨天生意很好,面包已经卖完了,那么顾客就需要等待
            if(index<0){// 下标小于0 就证明是 数组中没有面包了  ,就让消费者等待
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            //有面包可以卖
            //  卖了哪个面包
            System.out.println("[卖了]"+breads[index]);
            // 卖完面包  下标自动减-
            index--;
            this.notify();
        }
    
    }
    

    3.工厂类

    package 设计模式之生产者消费者模式;
    
    public class Factory implements Runnable {
        Market market;
    
        public Factory(Market market) {
            super();
            this.market = market;
        }
        @Override
        public void run() {
            for(int i=0;i<80;i++){
                market.getBread(new Bread("桃李牌"+i, 4.5));
            }
        }
    }
    

    4.消费者

    package 设计模式之生产者消费者模式;
    
    public class Customer implements Runnable {
        Market market;
        public Customer(Market market){
            this.market=market;
        }
    
        @Override
        public void run() {
            for(int i=0;i<80;i++){
                market.saleBread();
            }
        }
    
    }
    

    测试类

    package 设计模式之生产者消费者模式;
    
    public class Test {
        public static void main(String[] args){
            Market market=new Market();
            Factory factory=new Factory(market);
            Customer customer=new Customer(market);
            Thread thread=new Thread(factory,"生产者");
            Thread thread2=new Thread(customer,"消费者");
            thread.start();
            thread2.start();
        }
    }
    
  • 相关阅读:
    android Notification 通知栏点击不能跳转(转自:http://www.oschina.net/question/778954_212394)
    Android使用ContentObserver监听数据库变化(转自:http://www.blogjava.net/zhaojianhua/archive/2011/10/27/362204.html)
    cenos 6.4 samba 服务器安装与配置
    centos下nginx+tomcat部署java web全过程(包括在线离线安装Mysql等)
    python读取csv文件
    linux文件实时同步
    Linux 上安装 mysql
    Mysql5.7.20安装文档
    Cassanfra、Hbase和MongoDB的选取
    org.springframework.http.converter.HttpMessageConversionException: T
  • 原文地址:https://www.cnblogs.com/TCB-Java/p/6770126.html
Copyright © 2011-2022 走看看