生产者消费者问题

 这是一个面试经常被问到的问题,很多问题都可以转化为这个模型。

什么是生产者与消费者问题?举个例子,我们去吃自助餐,在自助餐的一个公共区域放着各种食物,消费者需要就自行挑选,当食物被挑没的时候,大家就等待,等候厨师做出更多再放到公共区域内供大家挑选;当公共区域食物达到一定数量,不能再存放的时候,此时没有消费者挑选,厨师此时等待,等公共区域有地方再存放食物时,再开始生产。这就是一个生产者与消费者问题。

根据这个例子,我们可以模拟一下场景,我们从这个例子中,显然看出我们需要制造一个公共区域,而且这个公共区域是有容量限制的,需要模拟各种食物,同时还需要模拟几个厨师也就是生产者,最后再模拟几个消费者。

首先呢,我们创建一个产品Product类,这个类就代表食物的模板,厨师们就生产这种类型的食物,类里面定义食物的ID和name这两个属性,代码如下:

复制代码
public class Product {     private int id;     private String name;     public Product(int id, String name) {         super();         this.id = id;         this.name = name;     }     @Override     public String toString() {         return "Product :id:"+id+",name:"+name;     }     public int getId() {         return id;     }     public void setId(int id) {         this.id = id;     }     public String getName() {         return name;     }     public void setName(String name) {         this.name = name;     } }
复制代码

接下来,我们创建那个公共区域,也就是一个容器,容器要么用数组保存,要么用集合,这里我们用集合LinkedList,然后呢,我们要清楚我们这个容器只能被创建一个,也就是公共区域只有一个,我们放也是放在这里面,取也是从这里面取,这里采用单例模式来保证只能创建一个容器实例,容器里面再定义放和取的方法,我们要加锁保证放和取的同步,以免发生线程安全问题,同时还要定义容器的最大容量,再放和取的同步方法里面,我们要判断是否容器内的食物超出了容器的最大容量,如果放的时候大于等于最大容量了,就不能再往里面放了,这时候厨师们(生产者)要等待;取的时候也一样,看是否容器内的食物个数为0,为0消费者们就要等待,最后我们在容器里面定义一个检查容器容量的方法,后面单独开启一个线程调用此方法,实时监测容器内食物的个数,一直在0-10之间,就说明我们写的代码没有问题,代码如下:

复制代码
public class Container {     //单例模式,保证只能创建一个容器实例    private static Container instance = null;     private Container(){}     public static Container getInstance(){         if(instance == null){             instance = new Container();         }         return instance;     }     private LinkedList<Product> list = new LinkedList<>();//容器    private int MAX = 10;//容器的最大容量     //放食物    public synchronized void putProduct(Product product){         while(li
                    
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信