多线程之生产者消费者模式的实现

在实际的开发工作中,会有这样的情节:某个模块负责生产数据(产品),而这些数据由另一个模块负责消费(此处的模块是广义的,可以是类、方法、线程、进程等)。在这里,负责生产数据的模块就是生产者,而负责处理这些数据的就是消费者。下面通过一个简单的例子说明

1.要生产和消费的产品

public class Product{
	private String name;//名字
	private double price;//价格
	private boolean flag = false;//产品是否生产完毕的标识,默认情况是没有生产完成。
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public double getPrice() {
		return price;
	}
	public void setPrice(double price) {
		this.price = price;
	}
	public boolean isFlag() {
		return flag;
	}
	public void setFlag(boolean flag) {
		this.flag = flag;
	}	
}

2.生产者生产产品

public class Producer extends Thread{
	private Product p;
	
	public Producer(Product p) {
		super();
		this.p = p;
	}
	@Override
	public void run() {
		int i=0;//为产生不同的产品
		while(true) {
			synchronized (p) {	//让生产者与消费者是同一个对象			
				if(p.isFlag()==false) {
					if(i%2==0) {
					p.setName("苹果");
					p.setPrice(12.0);
					}else {
					p.setName("香蕉");	
					p.setPrice(11.0);
					}
				}
				i++;
				System.out.println(Thread.currentThread().getName()+"生产了"+p.getName()+p.getPrice());
				p.setFlag(true);
				p.notifyAll();//唤醒消费者去消费
				try {
					p.wait();//生产者等待,并释放锁对象
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}				
			}
		}
	}
}

3.消费者消费产品

public class Customer extends Thread{
	private Product p;
	
	public Customer(Product p) {
		super();
		this.p = p;
	}
	@Override
	public void run() {
		while(true) {
			synchronized (p) {
				if(p.isFlag()==true) {//产品已经生产完毕
					System.out.println("消费者消费"+p.getName()+p.getPrice());					
				}
				p.setFlag(false);
				p.notifyAll();// 唤醒生产者去生产
				try {
					p.wait(); //消费者也等待了
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
}

4.测试类

public class Test {
	public static void main(String[] args) {
		Product p = new Product();//产品
		Producer producer = new Producer(p);//创建生产对象		
		Customer customer = new Customer(p);//创建消费者		
		producer.start();		//调用start方法开启线程
		customer.start();
	}
}

猜你喜欢

转载自blog.csdn.net/chenbingbing111/article/details/80070194