生产者消费者(二)

需求: 多个生产者不断的生产产品,多个消费者不断的消费产品,仓库可以存放10个产品。 第一批产品需要生产20个产品,并消费完毕。

其实使用wait/notify模式实现差不多,只是使用的时候要注意防止“死锁”。
blockingQueue的实现与notify的实现效率差不多.

package ycl.learn.effective.java.thread.pc;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;

public class PublicResourceBlockingQueue {

	private BlockingQueue<Product> queue = new LinkedBlockingQueue<Product>(10);

	private AtomicInteger index = new AtomicInteger(1); 

	public static final int MAX_RESOURCE = 20;

	public boolean increace() {
		try {
			if (isComplete()) {// 生产任务完成
				return false;
			}
			int tindex = index.getAndIncrement();
			Product p = new Product(tindex);
			queue.put(p);
			System.out.println(Thread.currentThread() + "increace:" + tindex);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		return true;
	}

	public boolean decreace() {
		try {
			if (isComplete() && isEmpty()) {
				return false;
			} 
			synchronized(this){
				if(!isEmpty()){
					Product p = queue.take();
					System.out.println(Thread.currentThread() + "decreace:" + p.index);
				}
			} 
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		return true;
	}

	/**
	 * 判断是否空了
	 */
	public boolean isEmpty() {
		return queue.isEmpty();
	}

	/**
	 * 判断生产完毕
	 */
	public boolean isComplete() {
		return index.get() > MAX_RESOURCE;
	}

	class Product {
		public int index;

		public Product(int index) {
			this.index = index;
		}
	}
}


public static void anotherone() throws InterruptedException{
		long start = System.currentTimeMillis();
		PublicResourceBlockingQueue ps = new PublicResourceBlockingQueue();
		CustomerB c = new CustomerB(ps);
		ProductorB p = new ProductorB(ps);
		Thread ct = new Thread(c,"customer0");
		Thread ct1 = new Thread(c,"customer1");
		Thread ct2 = new Thread(c,"customer2");
		Thread ct3 = new Thread(c,"customer3");
		Thread ct4 = new Thread(c,"customer4");
		Thread ct5 = new Thread(c,"customer5");
		Thread ct6 = new Thread(c,"customer6");
		
		Thread pt = new Thread(p,"productor0");
		Thread pt1 = new Thread(p,"productor1");
		Thread pt2 = new Thread(p,"productor2");
		Thread pt3 = new Thread(p,"productor3");
		Thread pt4 = new Thread(p,"productor4");
		Thread pt5 = new Thread(p,"productor5");
		Thread pt6 = new Thread(p,"productor6");
	  
		ct.start();
		ct1.start();
		ct2.start();
		ct3.start();
		ct4.start();
		ct5.start();
		ct6.start();
		
		pt.start();
		pt1.start();
		pt2.start();
		pt3.start();
		pt4.start();
		pt5.start();
		pt6.start();
		 
		
		ct.join();
		ct1.join();
		ct2.join();
		ct3.join();
		ct4.join();
		ct5.join();
		ct6.join();
		
		pt.join();
		pt1.join();
		pt2.join();
		pt3.join();
		pt4.join();
		pt5.join();
		pt6.join(); 
		System.out.println(System.currentTimeMillis()-start);//5531
	}


Thread[productor5,5,main]increace:5
Thread[productor2,5,main]increace:3
Thread[productor3,5,main]increace:4
Thread[productor6,5,main]increace:7
Thread[productor4,5,main]increace:6
Thread[productor1,5,main]increace:2
Thread[productor0,5,main]increace:1
Thread[productor1,5,main]increace:8
Thread[productor4,5,main]increace:9
Thread[customer1,5,main]decreace:6
Thread[productor0,5,main]increace:10
Thread[customer4,5,main]decreace:5
Thread[productor4,5,main]increace:11
Thread[productor6,5,main]increace:12
Thread[customer1,5,main]decreace:7
Thread[productor0,5,main]increace:13
Thread[customer2,5,main]decreace:4
Thread[productor3,5,main]increace:14
Thread[customer5,5,main]decreace:3
Thread[productor5,5,main]increace:15
Thread[customer4,5,main]decreace:2
Thread[productor0,5,main]increace:16
Thread[customer3,5,main]decreace:1
Thread[productor2,5,main]increace:17
Thread[customer6,5,main]decreace:8
Thread[customer0,5,main]decreace:9
Thread[customer3,5,main]decreace:10
Thread[customer5,5,main]decreace:11
Thread[productor1,5,main]increace:18
Thread[customer3,5,main]decreace:12
Thread[productor4,5,main]increace:19
Thread[productor5,5,main]increace:20
Thread[customer2,5,main]decreace:13
Thread[customer5,5,main]decreace:14
Thread[productor0,5,main] exist
Thread[customer1,5,main]decreace:15
Thread[productor5,5,main] exist
Thread[productor1,5,main] exist
Thread[customer4,5,main]decreace:16
Thread[customer2,5,main]decreace:17
Thread[productor3,5,main] exist
Thread[customer6,5,main]decreace:18
Thread[customer4,5,main]decreace:19
Thread[customer1,5,main]decreace:20
Thread[productor6,5,main] exist
Thread[customer5,5,main] exist
Thread[customer3,5,main] exist
Thread[productor2,5,main] exist
Thread[customer0,5,main] exist
Thread[productor4,5,main] exist
Thread[customer6,5,main] exist
Thread[customer2,5,main] exist
Thread[customer1,5,main] exist
Thread[customer4,5,main] exist
1234



实现的逻辑少了,这里需要注意的是,queue.take(),如果queue里再也不会有数据,将会”死锁“,防止多线程同时take最后一个,这里加了把锁。

你可能感兴趣的:(生产者消费者)