java多生產者消費者


想想很容易,寫起來卻並不是很順...磕磕巴巴寫好久有木有。補充回顧不少基礎知識。

參考:

一個生產者和一個消費者的情形。使用synchronized ,wait,notify。由於對於任何一方來說上鎖的一定是對方,最後notify沒什麼問題。但多個消費者會出錯。

 一生產者多消費者,不過這個問題的情景生產者的情形有點微妙(等消費完了再生產這點)。

多個生產者多個消費者一種的解決方案。(concurrent的lock,Condition,await,signal)

進階的多生產多消費者解決方案。


/**
 * 生產者
 * 
 * @author zoe
 * 
 */
class Productor implements Runnable {
	ProductBuffer buf;
	String name = "Productor";

	Productor(ProductBuffer buf, String name) {
		this.buf = buf;
		this.name = name;
	}

	public Product product() {
		Product p = new Product();
		System.out.println(this.name + "正在生產" + p.thisnum + "號...");
		try {
			Thread.sleep(300);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		return p;
	}

	public void run() {
		while (true) {
			Product p = product();
			try {
				buf.add(p);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}

/**
 * 消費者
 * 
 * @author zoe
 * 
 */
class Consumer implements Runnable {
	ProductBuffer buf;
	String name = "Consumer";

	Consumer(ProductBuffer buf, String name) {
		this.buf = buf;
		this.name = name;
	}


	public void consume(Product p) {
		System.out.println(this.name + "正在消費" + p.thisnum + "號...");
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	public void run() {
		while (true) {
			try {
				Product p =  buf.remove();
				consume(p);
				Thread.sleep(new Random().nextInt(1000));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}
/**
 * 產品
 * 
 * @author zoe
 * 
 */
class Product {
	static int num;
	int thisnum = num;
	Product() {
		num++;
	}
}

/**
 * 產品緩衝隊列
 * 
 * @author zoe
 * 
 */
class ProductBuffer {
	List<Product> buf = new ArrayList<Product>();
	static final int MAX = 10;
	// 多生產者消費者關鍵
	Lock l = new ReentrantLock();
	Condition empty = l.newCondition(); // 消費者的“空”位鎖
	Condition full = l.newCondition(); 		// 生產者的“滿”位鎖

	synchronized boolean isFull() {
		return buf.size() == MAX;
	}
	
	void add(Product p) throws Exception {
		l.lock();
		if (buf.size() == MAX) {
			full.await();
		}
		buf.add(p);
		System.out.println("新生產了一個!buf現有:" + buf.size() + "個\n---------");
		empty.signal();
		l.unlock();
	}

	Product remove() throws Exception {
		l.lock();
		if (buf.size() == 0) {
			empty.await();
		}
		Product p = buf.remove(buf.size() - 1);
		System.out.println("剛消費了一個!buf現有:" + buf.size() + "個\n---------");
		full.signal();
		l.unlock();
		return p;
	}


運行測試類

public class PAC {

	public static void main(String[] args) throws Exception {
		ProductBuffer buf = new ProductBuffer();
		Productor p1 = new Productor(buf, "生產者a");
		Productor p2 = new Productor(buf, "生產者b");
		Productor p3 = new Productor(buf, "生產者c");
		Consumer c = new Consumer(buf, "消費者1");
		Consumer c2 = new Consumer(buf, "消費者2");
		new Thread(p1).start();
		new Thread(p2).start();
		new Thread(p3).start();
		new Thread(c).start();
		new Thread(c2).start();
	}

}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章