多线程实现生产和消费

若⼲个⽣产者在⽣产产品,这些产品将提供给若⼲个消费者去消费,为了使⽣产者和消费者能并发执⾏,在两者之间设置⼀个能存储 多个产品的缓冲区,⽣产者将⽣产的产品放⼊缓冲区中,消费者从缓冲区中取⾛产品进⾏消费,显然⽣产者和消费者之间必须保持同 步,即不允许消费者到⼀个空的缓冲区中取产品,也不允许⽣产者向⼀个满的缓冲区中放⼊产品。

 

该案例共5个类:面包类,容器类,生产类,消费类,测试类

用到的方法:synchronized同步方法、wait让该方法进入等待、notifyAll唤醒通知所有线程

注意:生产类和消费类操作的是同一个容器,全程都是用的一个容器

 

1.面包类

public class Bread {

    private int id;
    private String productName;

    public Bread() {
        // TODO Auto-generated constructor stub
    }
    public Bread(int id, String productName) {
        super();
        this.id = id;
        this.productName = productName;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getProductName() {
        return productName;
    }
    public void setProductName(String productName) {
        this.productName = productName;
    }
    @Override
    public String toString() {
        return "Bread [id=" + id + ", productName=" + productName + "]";
    }
}

 

2.容器类:用于存放面包

public class BreadCon {
    //存放⾯包的数组
    private Bread[] cons=new Bread[6];
    //存放⾯包的位置
    private int index=0;

    //存放⾯包
    public synchronized void input(Bread b) { //锁this
        //判断容器有没有满
        while(index>=6) {
            try {
                this.wait();//释放锁,进入等待队列
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        cons[index]=b;
        System.out.println(Thread.currentThread().getName()+"⽣产了"+b.getId()+"");
        index++;
        //唤醒
        this.notifyAll();

    }

    //取出面包
    public synchronized void output() {//锁this
        while(index<=0) {
            try {
                this.wait();//释放锁,进入等待队列
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        index--;
        Bread b=cons[index];
        System.out.println(Thread.currentThread().getName()+"消费了"+b.getId()+" ⽣产者:"+b.getProductName());
        cons[index]=null;
        //唤醒⽣产者
        this.notifyAll();
    }
}

 

3.生产类:含生产方法,把面包放进容器

public class Prodcut implements Runnable {

    private BreadCon con;

    public Prodcut(BreadCon con) {
        super();
        this.con = con;
    }
    @Override
    public void run() {
        for(int i=0;i<30;i++) {
            con.input(new Bread(i, Thread.currentThread().getName()));
        }
    }

}

 

4.消费类:含消费方法,把面包从容器取出

public class Consume implements Runnable{
    private BreadCon con;

    public Consume(BreadCon con) {
        super();
        this.con = con;
    }
    @Override
    public void run() {
        for(int i=0;i<30;i++) {
            con.output();
        }
    }
}

 

5.测试类

public class Test {

    public static void main(String[] args) {
        //容器
        BreadCon con=new BreadCon();
        //⽣产和消费
        Prodcut prodcut=new Prodcut(con);
        Consume consume=new Consume(con);
        //创建线程对象
        Thread chenchen=new Thread(prodcut, "晨晨");
        Thread bingbing=new Thread(consume, "消费");
        Thread mingming=new Thread(prodcut, "明明");
        Thread lili=new Thread(consume, "莉莉");
        //启动线程
        chenchen.start();
        bingbing.start();
        mingming.start();
        lili.start();
    }
}

 

posted @ 2022-08-21 15:29  黄大虾  阅读(70)  评论(0编辑  收藏  举报