Liver's Java
          我不夠貪心!其實我應該明白,心有多貪,舞臺就會有多大!堅持!奮斗!
          posts - 4,  comments - 6,  trackbacks - 0
          昨天提到了線程,那么就不得不提到“生產者與消費者”這樣一個經典的線程同步問題

          場景描述:
              一個倉庫,生產者在工廠里生產了產品后,將產品存放到倉庫里,倉庫存放數量有限,當滿倉后,停止生產,直到有消費著將產品消費后才繼續(xù)生產;消費者從倉庫里提取產品,當倉庫空倉時,停止消費產品,直到倉庫中有產品時,才繼續(xù)消費產品。

          代碼的實現(調整線程sleep時間可以實現生產速度與消費速度的不同):
          TestProduceAndConsumer.java
          package com.nantian;

          import java.util.Random;

          public class TestProduceAndConsumer {
              
          public static void main(String[] args) {
                  
          // 創(chuàng)建一個工廠對象
                  ProductFactory pf = new ProductFactory();
                  
          // 創(chuàng)建一個生產者和一個消費者,傳遞工廠的引用,保證兩者操作的是同一個工廠
                  Producer p = new Producer(pf);
                  Consumer c 
          = new Consumer(pf);
                  
          // 啟動兩個線程
                  p.start();
                  c.start();
              }

          }


          // 產品工廠
          class ProductFactory {
              
          // product表示倉庫
              private char[] product = ' '' '' '' '' '};
              
          // flag標記產品數量
              private int flag = 0;

              
          // 生產產品
              public synchronized void produceProduct(char p) throws InterruptedException {
                  
          // 判斷產品是否滿倉,以便決定是否繼續(xù)生產
                  if (flag == product.length) {
                      
          this.wait();
                  }

                  
          // 當代碼執(zhí)行到這里,一定不是滿倉狀態(tài)
                  product[flag++= p;
                  
          // 查看此時倉庫狀態(tài)(這里不屬于業(yè)務邏輯部分)
                  System.out.print(p + "被生產,當前倉庫狀態(tài):");
                  
          for (char tmp : product) {
                      System.out.print(tmp);
                  }

                  System.out.println();
                  
          // 生產方法完成,如果存在等待隊列中的線程,應該喚醒
                  this.notifyAll();
              }

              
              
          // 消費產品
              public synchronized char consumeProduct() throws InterruptedException {
                  
          // 判斷倉庫是否空倉,以便決定是否消費產品
                  if(flag == 0{
                      
          this.wait();
                  }

                  
          // 當代碼執(zhí)行到這里,一定不是空倉狀態(tài)
                  char p = product[--flag]; product[flag]=' ';
                  
          // 查看此時倉庫狀態(tài)(這里不屬于業(yè)務邏輯部分)
                  System.out.print(p + "被消費,當前倉庫狀態(tài):");
                  
          for(char tmp : product) {
                      System.out.print(tmp);
                  }

                  System.out.println();
                  
          // 消費方法完成,如果存在等待隊列中的線程,應該喚醒
                  this.notifyAll();
                  
          return p;
              }

          }


          // 生產者
          class Producer extends Thread {
              
          private ProductFactory pf = null;
              
              
          public Producer(ProductFactory pf) {
                  
          this.pf = pf;
              }

              
              
          public void run() {
                  
          // 一共生產20個產品
                  for(int i=0; i<20; i++{
                      
          // 隨機產生一個大寫字母作為產品
                      Random r = new Random();
                      
          char p = (char)(r.nextInt(26+ 'A');
                      
          try {
                          
          // 產品入庫
                          pf.produceProduct(p);
                          
          // 故意sleep,以便消費線程有機會獲得CPU時間片,方便演示
                          Thread.sleep(200);
                      }
           catch (InterruptedException e) {
                          e.printStackTrace();
                      }

                  }

              }

          }


          // 消費者
          class Consumer extends Thread {
              
          private ProductFactory pf = null;
              
              
          public Consumer(ProductFactory pf) {
                  
          this.pf = pf;
              }

              
              
          public void run() {
                  
          // 一共消費20個產品
                  for(int i=0; i<20; i++{
                      
          try {
                          
          // 產品出庫
                          pf.consumeProduct();
                          
          // 故意sleep,以便生產線程有機會獲得CPU時間片,方便演示
                          
          // sleep時間稍微錯開,阻止同時競爭CPU時間片
                          Thread.sleep(300);
                      }
           catch (InterruptedException e) {
                          e.printStackTrace();
                      }

                  }

              }

          }
          posted on 2009-06-04 10:57 Liver 閱讀(1430) 評論(4)  編輯  收藏 所屬分類: CoreJava

          FeedBack:
          # re: 再談線程:生產者與消費者
          2009-06-04 16:22 | wuzhongxing
          利用jdk1.5的concurrent包里面的blockqueue,實現這種模式還是比較簡單的  回復  更多評論
            
          # re: 再談線程:生產者與消費者
          2009-06-04 18:10 | 樂蜂
          實現這種模式還是比較簡單的  回復  更多評論
            
          # re: 再談線程:生產者與消費者[未登錄]
          2009-06-06 16:57 | charlee
          // 判斷產品是否滿倉,以便決定是否繼續(xù)生產
          if (flag == product.length) {
          this.wait();
          }

          // 判斷倉庫是否空倉,以便決定是否消費產品
          if(flag == 0) {
          this.wait();
          }

          為什么要用if呢?你不覺得while更好么?  回復  更多評論
            
          # re: 再談線程:生產者與消費者
          2009-06-15 15:53 | 分享愛的空間
          言簡意賅,不錯。。。。
          希望看到更加深入的。  回復  更多評論
            

          只有注冊用戶登錄后才能發(fā)表評論。


          網站導航:
           

          <2009年6月>
          31123456
          78910111213
          14151617181920
          21222324252627
          2829301234
          567891011

          常用鏈接

          留言簿

          隨筆分類(5)

          隨筆檔案(5)

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 五大连池市| 贵南县| 平遥县| 淅川县| 苏尼特左旗| 南安市| 玛沁县| 福建省| 小金县| 敦煌市| 凌源市| 桐庐县| 高唐县| 资源县| 永昌县| 阿拉善右旗| 文山县| 松桃| 蚌埠市| 永顺县| 沈丘县| 化德县| 伊宁市| 高台县| 宜宾市| 淳安县| 平塘县| 筠连县| 石楼县| 武山县| 化州市| 孟村| 赣州市| 海晏县| 含山县| 贵阳市| 葵青区| 阿勒泰市| 岳池县| 沾益县| 彩票|