keep moving!

          We must not cease from exploration. And the end of all our exploring will be to arrive where we began and to know the place for the first time.
          隨筆 - 37, 文章 - 2, 評論 - 3, 引用 - 0
          數(shù)據(jù)加載中……

          Design Pattern: Producer Consumer 模式

          Producer Consumer模式與 Guarded Suspension 模式 是類似的,只不過Guarded Suspension模式並不限制緩衝區(qū)的長度,Producer Consumer模式假設(shè)所生產(chǎn)的產(chǎn)品放置在一個(gè)長度有限制的緩衝區(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ū)中。

          一個(gè)簡單的 UML 順序圖如下所示:
          ProducerConsumer
          簡單來說,Producer Consumer模式就像是加上了雙重防護(hù)與等待的Guarded Suspension模式,而它的兩個(gè)防護(hù)與等待的條件洽好相反,一個(gè)用Java實(shí)現(xiàn)的簡單流程架構(gòu)如下:
          • ProductTable.java
          import java.util.LinkedList;

          public class ProductTable {
          private LinkedList products = new LinkedList();

          public synchronized void addProduct(Product product) {
          while(products.size() >= 2) { // 容量限制為 2
          try {
          wait();
          }
          catch(InterruptedException e) {}
          }

          products.addLast(product);
          notifyAll();
          }

          public synchronized Product getProduct() {
          while(products.size() <= 0) {
          try {
          wait();
          }
          catch(InterruptedException e) {}
          }

          Product product = (Product) products.removeFirst();
          notifyAll();

          return product;
          }
          }

          以下舉一個(gè)最簡單的:生產(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ù)。
          • Producer.java
          public class Producer extends Thread {
          private ProductTable productTable;

          public Producer(ProductTable productTable) {
          this.productTable = productTable;
          }

          public void run() {
          System.out.println("Produce integer......");
          for(int product = 1; product <= 10; product++) {
          try {
          // wait for a random time
          Thread.sleep((int) Math.random() * 3000);
          }
          catch(InterruptedException e) {
          e.printStackTrace();
          }
          productTable.setIntProduct(product);
          }
          }
          }

          • Consumer.java
          public class Consumer extends Thread {
          private ProductTable productTable;

          public Consumer(ProductTable productTable) {
          this.productTable = productTable;
          }

          public void run() {
          for(int i = 1; i <= 10; i++) {
          try {
          // wait for a random time
          Thread.sleep((int) (Math.random() * 3000));
          }
          catch(InterruptedException e) {
          e.printStackTrace();
          }
          productTable.getProductInt();
          }
          }
          }

           

          生產(chǎn)者將產(chǎn)品放至桌上,而消費(fèi)者將產(chǎn)品從桌上取走,所以桌子是個(gè)維護(hù)是否讓被放置或消耗產(chǎn)品的地方,由它來決定誰必須等待與通知:
          • ProductTable.java
          public class ProductTable {
          private int productInt = -1; // -1 for no product

          public synchronized void setIntProduct(int product) {
          if(productInt != -1) {
          try {
          wait();
          }
          catch(InterruptedException e) {
          e.printStackTrace();
          }
          }

          productInt = product;
          System.out.println("set (" + product + ")");
          notify();
          }

          public synchronized int getProductInt() {
          if(productInt == -1) {
          try {
          wait();
          }
          catch(InterruptedException e) {
          e.printStackTrace();
          }
          }

          int p = productInt;
          System.out.println("Get (" + productInt + ")");
          productInt = -1;

          notify();

          return p;
          }
          }

          生產(chǎn)者會生產(chǎn)10個(gè)整數(shù),而消費(fèi)者會消耗10個(gè)整數(shù),由於桌上只能放置一個(gè)整數(shù),所以每生產(chǎn)一個(gè)就消耗一個(gè)。


          張金鵬 2007-04-17 10:56 發(fā)表評論

          文章來源:http://www.aygfsteel.com/jesson2005/articles/111195.html

          posted on 2008-09-07 11:06 大石頭 閱讀(191) 評論(0)  編輯  收藏 所屬分類: 多線程

          主站蜘蛛池模板: 宝山区| 铁力市| 周宁县| 阿克| 辽阳市| 扎鲁特旗| 无为县| 揭西县| 郑州市| 噶尔县| 霍城县| 石台县| 永福县| 灵武市| 建湖县| 黄浦区| 承德市| 根河市| 故城县| 永宁县| 千阳县| 崇州市| 深圳市| 禹城市| 正阳县| 淮南市| 裕民县| 永川市| 平顶山市| 温宿县| 嘉禾县| 象山县| 石泉县| 大余县| 和平区| 曲阜市| 海淀区| 原平市| 铁岭市| 南开区| 五家渠市|