?? producerconsumer.htm
字號(hào):
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<link rel="stylesheet" href="css/stdlayout.css" type="text/css">
<link rel="stylesheet" href="css/print.css" type="text/css">
<meta content="text/html; charset=gb2312" http-equiv="content-type">
<title>Producer Consumer 模式</title>
</head>
<body>
<h3><a href="http://caterpillar.onlyfun.net/GossipCN/index.html">From
Gossip@caterpillar</a></h3>
<h1><a href="CppGossip.html">Design Pattern: Producer Consumer 模式</a></h1>
Producer Consumer模式與 <a href="GuardedSuspension.htm">Guarded Suspension 模式</a>
是類似的,只不過(guò)Guarded Suspension模式并不限制緩沖區(qū)的長(zhǎng)度,Producer
Consumer模式假設(shè)所生產(chǎn)的產(chǎn)品放置在一個(gè)長(zhǎng)度有限制的緩沖區(qū)(就像是一個(gè)產(chǎn)品桌,它可以擺放的空間是有限的),如果緩沖區(qū)滿了,則生產(chǎn)者必須停止
繼續(xù)將產(chǎn)品放到緩沖區(qū)中,直到消費(fèi)者取走了產(chǎn)品而有了空間,而如果緩沖區(qū)中沒有產(chǎn)品,當(dāng)然消費(fèi)者必須等待,直到有新的產(chǎn)品放到緩沖區(qū)中。 <br>
<br>
一個(gè)簡(jiǎn)單的 UML 順序圖如下所示:<br>
<div style="text-align: center;"><img style="width: 642px; height: 526px;" alt="ProducerConsumer" title="ProducerConsumer" src="images/producerConsumer.jpg"><br>
</div>
簡(jiǎn)單來(lái)說(shuō),Producer Consumer模式就像是加上了雙重防護(hù)與等待的Guarded Suspension模式,而它的兩個(gè)防護(hù)與等待的條件洽好相反,一個(gè)用Java實(shí)現(xiàn)的簡(jiǎn)單流程架構(gòu)如下:<br>
<ul>
<li>ProductTable.java</li>
</ul>
<pre>import java.util.LinkedList;<br><br>public class ProductTable {<br> private LinkedList products = new LinkedList();<br><br> public synchronized void addProduct(Product product) {<br> while(products.size() >= 2) { // 容量限制為 2<br> try {<br> wait();<br> }<br> catch(InterruptedException e) {}<br> }<br><br> products.addLast(product);<br> notifyAll();<br> }<br> <br> public synchronized Product getProduct() {<br> while(products.size() <= 0) {<br> try {<br> wait();<br> }<br> catch(InterruptedException e) {}<br> }<br><br> Product product = (Product) products.removeFirst();<br> notifyAll();<br> <br> return product;<br> }<br>} </pre>
<br>
以下舉一個(gè)最簡(jiǎn)單的:生產(chǎn)者每次生產(chǎn)一個(gè)整數(shù)并放置在桌子上,而消費(fèi)者消耗整數(shù),桌子上一次只能放置一個(gè)整數(shù),如果桌子上已有整數(shù),則生產(chǎn)者等待消費(fèi)者將
整數(shù)消耗并通知生產(chǎn)者生產(chǎn)下一個(gè)整數(shù),如果桌子上沒有整數(shù),則消費(fèi)者等待生產(chǎn)者生產(chǎn)整數(shù)并通知消費(fèi)者可以消耗整數(shù)。<br>
<ul>
<li>Producer.java
</li>
</ul>
<pre>public class Producer extends Thread {<br> private ProductTable productTable;<br> <br> public Producer(ProductTable productTable) {<br> this.productTable = productTable;<br> }<br> <br> public void run() {<br> System.out.println("Produce integer......");<br> for(int product = 1; product <= 10; product++) {<br> try {<br> // wait for a random time<br> Thread.sleep((int) Math.random() * 3000);<br> }<br> catch(InterruptedException e) {<br> e.printStackTrace();<br> }<br> productTable.setIntProduct(product);<br> } <br> }<br>} <br></pre>
<br>
<ul>
<li> Consumer.java
</li>
</ul>
<pre>public class Consumer extends Thread {<br> private ProductTable productTable;<br> <br> public Consumer(ProductTable productTable) {<br> this.productTable = productTable;<br> }<br> <br> public void run() {<br> for(int i = 1; i <= 10; i++) {<br> try {<br> // wait for a random time<br> Thread.sleep((int) (Math.random() * 3000));<br> }<br> catch(InterruptedException e) {<br> e.printStackTrace();<br> }<br> productTable.getProductInt();<br> }<br> }<br>} <br></pre>
<p></p>
生產(chǎn)者將產(chǎn)品放至桌上,而消費(fèi)者將產(chǎn)品從桌上取走,所以桌子是個(gè)維護(hù)是否讓被放置或消耗產(chǎn)品的地方,由它來(lái)決定誰(shuí)必須等待與通知:
<ul>
<li> ProductTable.java
</li>
</ul>
<pre>public class ProductTable {<br> private int productInt = -1; // -1 for no product<br><br> public synchronized void setIntProduct(int product) {<br> if(productInt != -1) {<br> try {<br> wait();<br> }<br> catch(InterruptedException e) {<br> e.printStackTrace();<br> }<br> }<br><br> productInt = product;<br> System.out.println("set (" + product + ")");<br> notify();<br> }<br> <br> public synchronized int getProductInt() {<br> if(productInt == -1) {<br> try {<br> wait();<br> }<br> catch(InterruptedException e) {<br> e.printStackTrace();<br> }<br> }<br><br> int p = productInt;<br> System.out.println("Get (" + productInt + ")");<br> productInt = -1;<br> <br> notify();<br> <br> return p;<br> }<br>} <br></pre>
<br>
生產(chǎn)者會(huì)生產(chǎn)10個(gè)整數(shù),而消費(fèi)者會(huì)消耗10個(gè)整數(shù),由于桌上只能放置一個(gè)整數(shù),所以每生產(chǎn)一個(gè)就消耗一個(gè)。<br>
<br>
<br>
</body>
</html>
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -