細心!用心!耐心!

          吾非文人,乃市井一俗人也,讀百卷書,跨江河千里,故申城一游; 一兩滴辛酸,三四年學業,五六點粗墨,七八筆買賣,九十道人情。

          BlogJava 聯系 聚合 管理
            1 Posts :: 196 Stories :: 10 Comments :: 0 Trackbacks
          Producer Consumer模式與 Guarded Suspension 模式 是類似的,只不過Guarded Suspension模式並不限制緩衝區的長度,Producer Consumer模式假設所生產的產品放置在一個長度有限制的緩衝區(就像是一個產品桌,它可以擺放的空間是有限的),如果緩衝區滿了,則生產者必須停止繼續將產品放到緩衝區中,直到消費者取走了產品而有了空間,而如果緩衝區中沒有產品,當然消費者必須等待,直到有新的產品放到緩衝區中。

          一個簡單的 UML 順序圖如下所示:
          ProducerConsumer
          簡單來說,Producer Consumer模式就像是加上了雙重防護與等待的Guarded Suspension模式,而它的兩個防護與等待的條件洽好相反,一個用Java實現的簡單流程架構如下:
          • 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;
          }
          }

          以下舉一個最簡單的:生產者每次生產一個整數並放置在桌子上,而消費者消耗整數,桌子上一次只能放置一個整數,如果桌子上已有整數,則生產者等待消費者將整數消耗並通知生產者生產下一個整數,如果桌子上沒有整數,則消費者等待生產者生產整數並通知消費者可以消耗整數。
          • 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();
          }
          }
          }

           

          生產者將產品放至桌上,而消費者將產品從桌上取走,所以桌子是個維護是否讓被放置或消耗產品的地方,由它來決定誰必須等待與通知:
          • 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;
          }
          }

          生產者會生產10個整數,而消費者會消耗10個整數,由於桌上只能放置一個整數,所以每生產一個就消耗一個。
          posted on 2007-04-17 10:56 張金鵬 閱讀(510) 評論(0)  編輯  收藏 所屬分類: 多執行緒模式
          主站蜘蛛池模板: 白玉县| 昌都县| 绵阳市| 泽普县| 库伦旗| 鄂尔多斯市| 顺义区| 苏尼特左旗| 阿巴嘎旗| 务川| 衡山县| 徐汇区| 湾仔区| 沂南县| 阿鲁科尔沁旗| 绥芬河市| 肃南| 舞钢市| 屏东县| 赣州市| 澜沧| 东辽县| 清流县| 湖口县| 北海市| 郸城县| 云安县| 石门县| 和平县| 盐津县| 阆中市| 名山县| 东莞市| 崇明县| 吴江市| 贵州省| 三台县| 沭阳县| 略阳县| 安阳县| 托里县|