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

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

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

          import java.util.Random;

          public class TestProduceAndConsumer {
              
          public static void main(String[] args) {
                  
          // 創建一個工廠對象
                  ProductFactory pf = new ProductFactory();
                  
          // 創建一個生產者和一個消費者,傳遞工廠的引用,保證兩者操作的是同一個工廠
                  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 {
                  
          // 判斷產品是否滿倉,以便決定是否繼續生產
                  if (flag == product.length) {
                      
          this.wait();
                  }

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

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

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

                  
          // 當代碼執行到這里,一定不是空倉狀態
                  char p = product[--flag]; product[flag]=' ';
                  
          // 查看此時倉庫狀態(這里不屬于業務邏輯部分)
                  System.out.print(p + "被消費,當前倉庫狀態:");
                  
          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
          // 判斷產品是否滿倉,以便決定是否繼續生產
          if (flag == product.length) {
          this.wait();
          }

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

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

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


          網站導航:
           

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

          常用鏈接

          留言簿

          隨筆分類(5)

          隨筆檔案(5)

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 苏尼特右旗| 晋江市| 南乐县| 富裕县| 张家口市| 北辰区| 东源县| 白水县| 辽源市| 平武县| 静乐县| 齐河县| 沈丘县| 咸宁市| 潜江市| 金乡县| 胶州市| 将乐县| 湘阴县| 阜阳市| 呼和浩特市| 镇平县| 宁乡县| 通河县| 同心县| 嘉禾县| 翁牛特旗| 桐梓县| 宿州市| 观塘区| 宜丰县| 三原县| 岳西县| 凌云县| 额敏县| 永吉县| 祁门县| 六安市| 西华县| 东安县| 鹤山市|