一、简介
生产者消费者问题是线程模型中的经典问题。解决生产者/消费者问题有两种方法:一是采用某种机制保护生产者和消费者之间的同步;二是在生产者和消费者之间建立一个管道。第一种方式有较高的效率,并且易于实现,代码的可控制性较好,比较常用。第二种管道缓冲区不易控制,被传输数据对象不易于封装等,实用性不强。
本文介绍的时采用同步机制实现的生产者/消费者问题。
二、代码
1、Product产品类:
/* * 产品类
* @author gongyu * */ public class Product { private int id; private String name; public Product(int id, String name) { this.id = id; this.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; } @Override public String toString() { return "Product [id=" + id + ", name=" + name + "]"; } }
2、产品库房类ProductHouse
/* * 产品库房类 * */ public class ProductHouse { private Product[] products; private int max; private int index=-1; public ProductHouse(int max) { // TODO Auto-generated constructor stub this.max=max; products=new Product[max]; } /*生产者生成产品入库方法*/ public synchronized void push(Product product) { while(index>=max-1) { try { this.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } this.notifyAll();//唤醒别的线程 products[++index]=product; } /*消费者获取产品*/ public synchronized Product pop() { while(index<0) { try { this.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } this.notifyAll(); Product p=products[index--]; return p; } }
3、生产者线程 ProductThread
/** * 生产者线程 ProductThread * @author gongyu * */ public class ProductThread extends Thread{ private ProductHouse productHouse; public ProductThread(ProductHouse productHouse,String name) { // TODO Auto-generated constructor stub super(name); this.productHouse=productHouse; } public void run() { for(int i=0;i<10;i++) { Product p=new Product(i+1,this.getName()+"馒头"); System.out.println(this.getName()+"生产了"+p); productHouse.push(p); try { Thread.sleep(500); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
4、消费者线程 CustomerThread
/** * 消费者线程 CustomerThread * @author gongyu * */ public class CustomerThread extends Thread{ private ProductHouse productHouse; public CustomerThread(ProductHouse productHouse,String name) { // TODO Auto-generated constructor stub super(name); this.productHouse=productHouse; } public void run() { for(int i=0;i<5;i++) { Product p=productHouse.pop(); System.out.println(this.getName()+"消费了"+p); } try { Thread.sleep(300); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
5、测试类
public class Test01 { public static void main(String[] args) { ProductHouse ph=new ProductHouse(30); ProductThread p1=new ProductThread(ph,"老张"); ProductThread p2=new ProductThread(ph,"老李"); ProductThread p3=new ProductThread(ph,"老杨"); ProductThread p4=new ProductThread(ph,"老王"); CustomerThread c1=new CustomerThread(ph,"小红"); CustomerThread c2=new CustomerThread(ph,"小绿"); CustomerThread c3=new CustomerThread(ph,"小蓝"); CustomerThread c4=new CustomerThread(ph,"小白"); CustomerThread c5=new CustomerThread(ph,"小黑"); CustomerThread c6=new CustomerThread(ph,"小灰"); p1.start();p2.start();p3.start();p4.start(); c1.start();c2.start();c3.start();c4.start();c5.start();c6.start(); } }
浙公网安备 33010602011771号