美文网首页
经典生产者消费者问题

经典生产者消费者问题

作者: 孙浩j | 来源:发表于2017-11-16 14:03 被阅读7次

    需求分析:假设生产者生产馒头,有一个容器只能装10个馒头,
    1.当容器里没有馒头时,消费者不能消费(消费者的线程进入等待),当生产者生产一个馒头就叫醒了这个等待消耗的消费者线程。
    2.当容器馒头超过10个,生产者不能生产(生产者的线程进入等待),当消费者消耗了一个以后,就叫醒了等待的生产者线程,生产者可以生产。
    3.生产一个馒头就把馒头放到容器里,消费一个馒头就把馒头从容器里删除
    4.生产,消费不能同时进行,加锁
    类:馒头类,容器类,生产者类,消费者类

    资源类:

    public class ManTou {
        int id;
        public ManTou (int id){
            this.id=id;
        }   
        public int getId(){
            return id;
        }
        @Override
        public String toString() {
            return "ManTou [id=" + id + "]";
        }
        
    }
    
    

    容器类

    import java.util.List;
    import java.util.LinkedList;
    public class LanZi {
        ManTou [] m=new ManTou[10];  //放馒头         //建立数组用于放馒头
        int index=0;   //放馒头的位置
        public synchronized void  push(ManTou mt) throws InterruptedException{   //生产馒头
            if(index==m.length){            //篮子装的额馒头数量等于容量时,线程挂起
                wait();//这个地方不用if else 原因是  
            }else{
            m[index]=mt;                       //生产馒头
            
            System.out.println(m[index].id+"号馒头生产完成");
            for(int i=0;i<m.length;i++){
                if(m[i]!=null){
            System.out.println("篮子里有"+(m[i])+"馒头");//显示容器里的馒头
                }
                
            }
            notify();           //用于叫醒当没有馒头时,等待的消费者
            index++;    //放馒头的位置+1
            
            Thread.sleep(1000);
            }
            
        }
        public synchronized void pop() throws InterruptedException{                     //拿馒头
            
            if(index==0){  //当没有馒头,线程挂起等待
                wait(); 
            }else{          //消费馒头
               
            index--;     //由于生产完,放馒头的地方就加了,所以消耗就要消耗前一个位置的馒头
            System.out.println("吃了"+m[index].id+"号馒头");
            m[index]=null;     //吃完之后容器里就没有这个馒头了
                    notify();       //用于叫醒馒头满了而停下的生产者
            Thread.sleep(1000);
            }
        }
    }
    
    

    生产者类

    public class Produce implements Runnable {
        LanZi l=null;
        public Produce(LanZi l){ //确保生产者消费者使用的是同一个篮子
            this.l=l;
        }
    
        @Override
        public void run() {
            // TODO Auto-generated method stub
                
                int i=0;
                ManTou m=null;
                while(true){                          
                    boolean b=true;
                    for(int j=0;j<l.m.length;j++){
                        if(l.m[j]==null){    //找到数组里没放馒头的位置
                        b=false;
                        break;     //没有位置放的话就不要生产了
                    }
                    }                   
                    if(!b){
                                                           //如果为空可以生产馒头
                    m=new ManTou(++i);   //新馒头
                    }
                    try {
                        l.push(m);     //将生产的馒头放入数组
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }               
            }   
        }
    }
    
    

    消费者类

    public class Consume implements Runnable{
        LanZi l=null;
        public Consume(LanZi l){
            this.l=l;
        }
        @Override
        public void run() {
            // TODO Auto-generated method stub
            while(true){
            try {
                l.pop();
            } catch (InterruptedException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            
            try {
                Thread.sleep(60);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            }
        }
    
    }
    
    

    相关文章

      网友评论

          本文标题:经典生产者消费者问题

          本文链接:https://www.haomeiwen.com/subject/oiylvxtx.html