经典生产者消费者问题

2017-11-16  本文已影响7人  孙浩j

需求分析:假设生产者生产馒头,有一个容器只能装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();
        }
        }
    }

}

上一篇下一篇

猜你喜欢

热点阅读