生产者与消费者模式:生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。这个阻塞队列就是用来给生产者和消费者解耦的。

一、一个商品(版本1)

//商品类
class Goods{
	private String goodsName;	//商品名称
	private int count;	//商品数量
	//生产方法
	public synchronized void set(String goodsName) {
		this.goodsName = goodsName;
		//生产一个商品
		this.count = count + 1;
		System.out.println(toString());
	}
	//消费方法
	public synchronized void get() {
		//消费一个商品
		this.count = count - 1;
		System.out.println(toString());
	}
	@Override
	public String toString() {
		return "Goods [goodsName=" + goodsName + ", count=" + count + "]";
	}
}
//生产者类
class Producer implements Runnable{
	private Goods goods;
	public Producer(Goods goods) {
		this.goods = goods;
	}
	@Override
	public void run() {
		this.goods.set("四驱车");
	}
}
//消费者类
class Consumer implements Runnable{
	private Goods goods;
	public Consumer(Goods goods) {
		this.goods = goods;
	}
	@Override
	public void run() {
		this.goods.get();
	}
}
public class Test{
	public static void main(String[] args) throws InterruptedException {
		Goods goods = new Goods();
		Thread produceThread = new Thread(new Producer(goods),"生产者");
		Thread consumerThread = new Thread(new Consumer(goods),"消费者");
		//启用生产者线程
		produceThread.start();
		Thread.sleep(1000);
		//启用消费者线程
		consumerThread.start();
	}
}



二、一个商品(版本2)

//商品类
class Goods{
	private String goodsName;	//商品名称
	private int count;	//商品个数
	//生产方法
	public synchronized void set(String goodsName) throws InterruptedException {
		//此时还有商品没被消费,等待消费者
		if(this.count > 0) {
			System.out.println("还有库存,等待消费者");
			wait();
		}
		this.goodsName = goodsName;
		//生产一个商品
		this.count = count + 1;
		Thread.sleep(1000);
		System.out.println("生产" + toString());
		//生产完商品后通知消费者可以消费了
		notify();
	}
	//消费方法
	public synchronized void get() throws InterruptedException {
		//此时还没有商品,等待生产者生产商品
		if(this.count == 0) {
			System.out.println("商品卖完了,等待生产者");
			wait();
		}
		//消费一个商品
		this.count = count - 1;
		System.out.println("消费" + toString());
		//消费完商品后通知生产者可以生产了
		notify();
	}
	@Override
	public String toString() {
		return "Goods [goodsName=" + goodsName + ", count=" + count + "]";
	}
}
//生产者类
class Producer implements Runnable{
	private Goods goods;
	public Producer(Goods goods) {
		this.goods = goods;
	}
	@Override
	public void run() {
		try {
			this.goods.set("四驱车");
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
//消费者类
class Consumer implements Runnable{
	private Goods goods;
	public Consumer(Goods goods) {
		this.goods = goods;
	}
	@Override
	public void run() {
		try {
			this.goods.get();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
public class Test{
	public static void main(String[] args) {
		Goods goods = new Goods();
		Thread produceThread = new Thread(new Producer(goods),"生产者");
		Thread consumerThread = new Thread(new Consumer(goods),"消费者");
		//启用消费者线程
		consumerThread.start();
		//启用生产者线程
		produceThread.start();
	}
}


版本2和版本1的区别是,如果版本1先启用消费者进程,则会出现count为-1,而版本2不会出现这种情况。


三、多个生产者与消费者

//商品类
class Goods{
	private String goodsName;	//商品名称
	private int count;	//商品个数
	//生产方法
	public synchronized void set(String goodsName) throws InterruptedException {
		//此时还有商品没被消费,等待消费者
		while(this.count > 0) {
			System.out.println("还有产品,等待消费者");
			wait();
		}
		this.goodsName = goodsName;
		this.count = count + 1;
		System.out.println("生产" + toString());
		Thread.sleep(1000);
		//生产完商品后通知消费者可以消费了
		notifyAll();
	}
	//消费方法
	public synchronized void get() throws InterruptedException {
		//此时还没有商品,等待生产者生产商品
		while(this.count == 0) {
			System.out.println("产品已卖完,等待生产者");
			wait();
		}
		this.count = count - 1;
		System.out.println("消费" + toString());
		Thread.sleep(1000);
		//消费完商品后通知生产者可以生产了
		notifyAll();
	}
	@Override
	public String toString() {
		return "Goods [goodsName=" + goodsName + ", count=" + count + "]";
	}
}
//生产者类
class Producer implements Runnable{
	private Goods goods;
	public Producer(Goods goods) {
		this.goods = goods;
	}
	@Override
	public void run() {
		while(true) {
			try {
				this.goods.set("四驱车");
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}
//消费者类
class Consumer implements Runnable{
	private  Goods goods;
	public Consumer(Goods goods) {
		this.goods = goods;
	}
	@Override
	public void run() {
		while(true) {
			try {
				this.goods.get();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}
public class Test{
	public static void main(String[] args) {
		Goods goods = new Goods();
		//存储生产者、消费者线程
		ArrayList<Thread> threadList = new ArrayList<>();
		//十个生产者
		for(int i = 0;i < 10;i++) {
			Thread produceThread = new Thread(new Producer(goods));
			threadList.add(produceThread);
		}
		//六个消费者
		for(int i = 0;i < 6;i++) {
			Thread consumeThread = new Thread(new Consumer(goods));
			threadList.add(consumeThread);
		}
		//启动所有线程
		for(Thread thread : threadList) { 
			thread.start();
		}
	}
}