多线程实现生产和消费
若⼲个⽣产者在⽣产产品,这些产品将提供给若⼲个消费者去消费,为了使⽣产者和消费者能并发执⾏,在两者之间设置⼀个能存储 多个产品的缓冲区,⽣产者将⽣产的产品放⼊缓冲区中,消费者从缓冲区中取⾛产品进⾏消费,显然⽣产者和消费者之间必须保持同 步,即不允许消费者到⼀个空的缓冲区中取产品,也不允许⽣产者向⼀个满的缓冲区中放⼊产品。
该案例共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(); } }