Java 线程与并发研究系列五(生产者与消费者)

生产者与消费者问题是了解多线程的基本实例,就像hello world之于语言学习,下面我们就编写一个生产者-消费者的示例

public class Test {

	public static void main(String[] args) {
		Storage storage = new Storage(20);
		
		ExecutorService exes = Executors.newCachedThreadPool();
		for (int i = 0; i < 10; i++) {
			exes.submit(new Producer(storage));
			exes.submit(new Consumer(storage));
		}
		try {
			TimeUnit.SECONDS.sleep(5);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		exes.shutdownNow();
	}
}

class Producer implements Runnable{
	Storage storage;
	
	public Producer(Storage storage){
		this.storage = storage;
	}
	
	@Override
	public void run() {
		try {
			storage.produce();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}
class Consumer implements Runnable{

	Storage storage;
	
	public Consumer(Storage storage){
		this.storage = storage;
	}
	
	@Override
	public void run() {
		try {
			storage.consume();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}	
}

class Storage{
	private static final int max = 30;
	private int num;
	
	public Storage(int num){
		this.num = num;
	}
	
	public synchronized void produce()throws InterruptedException{
		while(num>=max){
			wait();
		}
		num+=5;
		System.out.println("生产产品数:"+5+" 仓库还剩产品数:"+num);
		notifyAll();
	}
	
	public synchronized void consume()throws InterruptedException{
		while(num<7){
			wait();
		}
		num-=7;
		System.out.println("消费产品数:"+7+" 仓库还剩产品数:"+num);
		notifyAll();
	}
}


以上是通过wait()和notifyAll synchronized关键字进行线程之间的同步,现在我们尝试另外一种方法,通过使用同步队列来解决任务的协作

问题,如果消费者试图从队列中获取对象,而此时队列为空,阻塞队列就会挂起消费者线程,同理如果参考已经满了,生产者试图向队列

中添加对象,此时队列将挂起生产者线程。

public class MyData{
	
	public static void main(String[] args) {
		Storage storage = new Storage();
		
		ExecutorService exes = Executors.newCachedThreadPool();
		for (int i = 0; i < 10; i++) {
			exes.submit(new Producer(storage));
			exes.submit(new Consumer(storage));
		}
		try {
			TimeUnit.SECONDS.sleep(5);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		exes.shutdownNow();
		
		System.out.println("仓库最后剩余数:"+storage.queue.size());
	}
}

class Producer implements Runnable{
	Storage storage;
	
	public Producer(Storage storage){
		this.storage = storage;
	}
	
	@Override
	public void run() {
		try {
			storage.produce();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}
class Consumer implements Runnable{

	Storage storage;
	
	public Consumer(Storage storage){
		this.storage = storage;
	}
	
	@Override
	public void run() {
		try {
			storage.consume();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}	
}

class Storage{
	private static final int max = 30;
	public BlockingQueue<Product> queue;
	
	public Storage(){
		this.queue = new LinkedBlockingQueue<Product>();
	}
	
	public void produce()throws InterruptedException{
		if(queue.size()<max){
			queue.put(new Product());
			System.out.println("生产一个产品,仓库产品个数:"+queue.size());
		}
	}
	
	public void consume()throws InterruptedException{
		if(queue.size()>0){
			queue.take();
			System.out.println("消费一个产品,仓库产品个数:"+queue.size());
		}
	}
}

class Product{
	public Product(){}
}


 

你可能感兴趣的:(Java 线程与并发研究系列五(生产者与消费者))