posts - 297,  comments - 1618,  trackbacks - 0
                 這是以前為一師妹做的一機試題,雖后來因為她編程底子太弱,沒能獲得那份工作,拿在這里與大家共享之。
                 題目如下:
                在生產(chǎn)者/消費者模型中,生產(chǎn)者Producer負責生產(chǎn)數(shù)據(jù),而消費者Consumer負責使用數(shù)據(jù)。多個生產(chǎn)者線程會在同一時間運行,生產(chǎn)數(shù)據(jù),并放到內(nèi)存中一個共享的區(qū)域。期間,多個消費者線程讀取內(nèi)存共享區(qū),消費里面的數(shù)據(jù)。
          要求:
               1. 針對上面的場景,請創(chuàng)建2個類,一個叫Producer,一個叫Consumer. 
               2. Producer類繼承Thread類,并實現(xiàn)把數(shù)據(jù)放到內(nèi)存共享區(qū)的功能,這個功能要求是線程安全的。在個Producer類中的run方法中,循環(huán)20次,每次把一個整數(shù)放到內(nèi)存共享區(qū)中。
               3. Consumer類也繼承Thread類,并實現(xiàn)在沒有沖突的情況下,從內(nèi)存共享區(qū)中獲取數(shù)據(jù),并在標準輸出設備中打印輸出。輸出的格式為:Consumer thread X retrieved integer Y.
               4. 最后,創(chuàng)建一個main class,創(chuàng)建10個Procuder線程和4個消費者線程并啟動這些線程。
               5. 要求有效代碼行數(shù)盡量少,最好不超過100行。
               我大概的做了一下,以下是我的代碼實現(xiàn):
               一. 消費者類
               
          /**
           * 消費者類
           * 
          @author Amigo Xie(xiexingxing1121@126.com)
           *
           
          */

          class Consumer extends Thread 
              
          private Conn conn; 
              
          private int consumerNumber;
              
          public Consumer(Conn conn1, int conNum) 
                  conn 
          = conn1;
                  consumerNumber 
          = conNum;
              }

              
              
          public void run() 
                  
          for (int i = 0; i < 50; i++
                      System.out.println(
          "Consumer thread " +  consumerNumber + " retrieved integer: " + conn.read()); //
                      try 
                          sleep((
          int) (Math.random() * 2000)); 
                      }
           catch (InterruptedException e) {
                          e.printStackTrace();
                      }
           
                  }
           
              }

          }

              
                二. 生產(chǎn)者類
              
          /**
           * 生產(chǎn)者類
           * 
          @author Amigo Xie(xiexingxing1121@126.com)
           *
           
          */

          class Producer extends Thread 
              
          private Conn conn;

              
          public Producer(Conn conn1) 
                  conn 
          = conn1;
              }

              
              
          public void run() 
                  
          for (int i = 0; i < 20; i++
                      conn.add(i);
                  }
           
              }
           
          }

               
                 三. 線程通信類
          /**
           * 線程通信類
           * 
          @author Amigo Xie(xiexingxing1121@126.com)
           *
           
          */

          class Conn 
              
          private int buffer[] = new int[200]; //10個Procuder線程,需存放200個變量
              private int next = 0//Flags to keep track of our int buffer status 
              private boolean isFull = false
              
          private boolean isEmpty = true

              
          /**
               * method to read int
               * 
          @return
               
          */

              
          public synchronized int read() 
                  
          while (isEmpty == true//We can't read if there is nothing in our int buffer 
                      try 
                          wait();
          //we'll exit this when isEmpty turns false
                      }
          catch (InterruptedException e) {
                          e.printStackTrace();
                      }
           
                  }
           
                  
                  next
          --//decrement the count,since we're going to read one int 
                  if (next == 0
                      isEmpty 
          = true//Did we read the last letter? 
                  }

                  
                  isFull 
          = false;
                  notify();
                  
          return (buffer[next]);//return the int to the thread that is reading 
              }


              
          /**
               * method to add integer to the buffer
               * 
          @param number
               
          */

              
          public synchronized void add(int number) {  
                  
          while (isFull == true ) //Wait around until there's room to add another letter
                      try 
                          wait();
          //This will exit when isFull turns false 
                      }
          catch (InterruptedException e) {
                          e.printStackTrace();
                      }
           
                  }


                  next
          ++//add the integer to the next available spot buffer[next]=number;Change the next available spot 
                  if (next == 200
                      isFull 
          = true//Are we full?
                  }
           else {
                      buffer[next] 
          = number; 
                  }

                  isEmpty 
          =false
                  notify(); 
              }
           
          }


              四. 測試類
             
          /**
           * 測試類
           * 
          @author Amigo Xie(xiexingxing1121@126.com)
           *
           
          */

          public class ProducerAndConsumerTest {

              
          /**
               * 
          @param args
               
          */

              
          public static void main(String[] args) {
                  Conn conn 
          = new Conn();
                  Producer pro1 
          = new Producer(conn);
                  Producer pro2 
          = new Producer(conn);
                  Producer pro3 
          = new Producer(conn);
                  Producer pro4 
          = new Producer(conn);
                  Producer pro5 
          = new Producer(conn);
                  Producer pro6 
          = new Producer(conn);
                  Producer pro7 
          = new Producer(conn);
                  Producer pro8 
          = new Producer(conn);
                  Producer pro9 
          = new Producer(conn);
                  Producer pro10 
          = new Producer(conn);
                  
                  Consumer consumer1 
          = new Consumer(conn, 1);
                  Consumer consumer2 
          = new Consumer(conn, 2);
                  Consumer consumer3 
          = new Consumer(conn, 3);
                  Consumer consumer4 
          = new Consumer(conn, 4);
                  
                  pro1.start();
                  pro2.start();
                  pro3.start();
                  pro4.start();
                  pro5.start();
                  pro6.start();
                  pro7.start();
                  pro8.start();
                  pro9.start();
                  pro10.start();
                  
                  consumer1.start();
                  consumer2.start();
                  consumer3.start();
                  consumer4.start();
              }


          }


                  近來發(fā)現(xiàn),去看以前的代碼,都覺得有點傻傻滴,現(xiàn)在的話如果去實現(xiàn)大抵會有所改進,我在進步中嗎?啊哈。
          posted on 2007-04-11 21:52 阿蜜果 閱讀(6294) 評論(8)  編輯  收藏 所屬分類: Java


          FeedBack:
          # re: 生產(chǎn)者/消費者模型模擬實現(xiàn)[未登錄]
          2007-04-11 23:01 | Tony
          樓主的測試類可不怎么幽雅,呵呵  回復  更多評論
            
          # re: 生產(chǎn)者/消費者模型模擬實現(xiàn)
          2007-04-11 23:15 | 阿蜜果
          @Tony
          啊哈,是極其不優(yōu)雅,以前寫的代碼哩
          現(xiàn)在去看從前寫的代碼
          有時真想對它動動刀子。。。  回復  更多評論
            
          # re: 生產(chǎn)者/消費者模型模擬實現(xiàn)
          2007-04-12 10:28 | 劉甘泉
          哇,測試好多代碼~~~~~~~  回復  更多評論
            
          # re: 生產(chǎn)者/消費者模型模擬實現(xiàn)
          2007-04-13 09:19 | riverbuilding
          public synchronized void add
          public synchronized int read
          這兩個方法造成的結果是生產(chǎn)者生產(chǎn)時消費者不能同時消費,這個邏輯不多。  回復  更多評論
            
          # re: 生產(chǎn)者/消費者模型模擬實現(xiàn)
          2007-04-13 13:53 | hs
          樓上說的是,read方法的同步應該去掉。
          另外發(fā)表一下個人意見,供大家參考指正:
          以上的實現(xiàn)方法體現(xiàn)不出數(shù)據(jù)共享,或者說共享對象不明確。如果共享對象做成一個singleton,可能會好些,更能體現(xiàn)共享的含義。
          新建 一個對象,然后通過傳遞該對象到不同的生產(chǎn)者或消費者以達到共享對象,這種做法欠妥。這種做法導致邏輯不清析,同時可能會產(chǎn)生過期引用對象,當你認為該對象已經(jīng)無用的時候,可能該對象還被引用著,導致不能回收,你也很難跟宗和控制這個對象。把共享對象做成singleton,使共享的邏輯清析,也明確該對象永遠存在。  回復  更多評論
            
          # re: 生產(chǎn)者/消費者模型模擬實現(xiàn)[未登錄]
          2007-04-13 14:14 | 阿蜜果
          @hs
          @riverbuilding
          :)
          感謝你們的建議
          這是以前寫的一程序
          打算抽空再重寫一次。  回復  更多評論
            
          # re: 生產(chǎn)者/消費者模型模擬實現(xiàn)
          2007-04-13 16:59 | att
          用 synchronizedList 代替你的那么通信類吧。  回復  更多評論
            
          # re: 生產(chǎn)者/消費者模型模擬實現(xiàn)
          2010-07-22 19:07 | Ilovesola
          看了你的幾篇文章,覺得還可以,所以多多關注了一下.

          能寫好生產(chǎn)-消費者的程序員不多.
          代碼我隨便看了一下 和評論也看了一下
          有人建議去 read同步方法, 這肯定不能去的,只能說明他們 對生產(chǎn)消費模弄理解不夠深.

          notify 建議換成 notifyAll();

          最后,說明下,不知道你測試過沒,你的程序貌似有個很嚴重的邏輯錯誤.

          就是 應該首先add/read 對象,然后再next++ ,next--

          我舉個例子,
          你執(zhí)行 main方法 A線程 執(zhí)行add方法 99次,然后B線程去read, 這時候 next=99,它就 read buffer[99] , 應該要read buffer[0]的
            回復  更多評論
            
          <2007年4月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

                生活將我們磨圓,是為了讓我們滾得更遠——“圓”來如此。
                我的作品:
                玩轉(zhuǎn)Axure RP  (2015年12月出版)
                

                Power Designer系統(tǒng)分析與建模實戰(zhàn)  (2015年7月出版)
                
               Struts2+Hibernate3+Spring2   (2010年5月出版)
               

          留言簿(263)

          隨筆分類

          隨筆檔案

          文章分類

          相冊

          關注blog

          積分與排名

          • 積分 - 2296321
          • 排名 - 3

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 杭锦旗| 龙口市| 宝兴县| 铜陵市| 涿鹿县| 嘉荫县| 蓝田县| 旌德县| 芒康县| 滕州市| 丰顺县| 务川| 南召县| 鄂温| 乳源| 房山区| 息烽县| 砚山县| 申扎县| 鹤山市| 武陟县| 汪清县| 晋州市| 巫溪县| 奉节县| 扬中市| 奇台县| 青神县| 昔阳县| 拉萨市| 平昌县| 太仓市| 博罗县| 大同县| 明溪县| 禄丰县| 贺兰县| 商都县| 泰顺县| 金寨县| 奉新县|