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, 評(píng)論 - 3, 引用 - 0
          數(shù)據(jù)加載中……

          Design Pattern: Producer Consumer 模式

          Producer Consumer模式與 Guarded Suspension 模式 是類(lèi)似的,只不過(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ū)中沒(méi)有產(chǎn)品,當(dāng)然消費(fèi)者必須等待,直到有新的產(chǎn)品放到緩衝區(qū)中。

          一個(gè)簡(jiǎn)單的 UML 順序圖如下所示:
          ProducerConsumer
          簡(jiǎn)單來(lái)說(shuō),Producer Consumer模式就像是加上了雙重防護(hù)與等待的Guarded Suspension模式,而它的兩個(gè)防護(hù)與等待的條件洽好相反,一個(gè)用Java實(shí)現(xiàn)的簡(jiǎ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è)最簡(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ù),如果桌子上沒(méi)有整數(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)品的地方,由它來(lái)決定誰(shuí)必須等待與通知:
          • 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)者會(huì)生產(chǎn)10個(gè)整數(shù),而消費(fèi)者會(huì)消耗10個(gè)整數(shù),由於桌上只能放置一個(gè)整數(shù),所以每生產(chǎn)一個(gè)就消耗一個(gè)。



          文章來(lái)源:http://www.aygfsteel.com/jesson2005/articles/111195.html

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

          主站蜘蛛池模板: 曲沃县| 白山市| 依兰县| 招远市| 黄平县| 灵丘县| 渭源县| 青阳县| 芷江| 奈曼旗| 武宣县| 都匀市| 崇义县| 班玛县| 孝昌县| 呼图壁县| 开远市| 肃宁县| 瑞金市| 明溪县| 巴林右旗| 义马市| 乳山市| 修水县| 金坛市| 普兰店市| 福州市| 长丰县| 兴城市| 灵丘县| 青神县| 南丹县| 高邮市| 文昌市| 阜宁县| 松滋市| 溧阳市| 长沙县| 吉木乃县| 德格县| 浙江省|