隨筆-59  評(píng)論-31  文章-0  trackbacks-0
          import java.util.concurrent.ArrayBlockingQueue;
          import java.util.concurrent.BlockingQueue;
          import java.util.concurrent.ExecutorService;
          import java.util.concurrent.Executors;
           
          /**
              本例介紹一個(gè)特殊的隊(duì)列:BlockingQueue,如果BlockQueue是空的,從BlockingQueue取東西的操作將會(huì)被阻斷進(jìn)入等待狀態(tài),直到BlockingQueue進(jìn)了東西才會(huì)被喚醒.同樣,如果BlockingQueue是滿的,任何試圖往里存東西的操作也會(huì)被阻斷進(jìn)入等待狀態(tài),直到BlockingQueue里有空間才會(huì)被喚醒繼續(xù)操作.
              本例再次實(shí)現(xiàn)11.4線程----條件Condition中介紹的籃子程序,不過(guò)這個(gè)籃子中最多能放的蘋果數(shù)不是1,可以隨意指定.當(dāng)籃子滿時(shí),生產(chǎn)者進(jìn)入等待狀態(tài),當(dāng)籃子空時(shí),消費(fèi)者等待.
           
          */
          /**
              使用BlockingQueue的關(guān)鍵技術(shù)點(diǎn)如下:
              1.BlockingQueue定義的常用方法如下:
                  1)add(anObject):把a(bǔ)nObject加到BlockingQueue里,即如果BlockingQueue可以容納,則返回true,否則招聘異常
                  2)offer(anObject):表示如果可能的話,將anObject加到BlockingQueue里,即如果BlockingQueue可以容納,則返回true,否則返回false.
                  3)put(anObject):把a(bǔ)nObject加到BlockingQueue里,如果BlockQueue沒(méi)有空間,則調(diào)用此方法的線程被阻斷直到BlockingQueue里面有空間再繼續(xù).
                  4)poll(time):取走BlockingQueue里排在首位的對(duì)象,若不能立即取出,則可以等time參數(shù)規(guī)定的時(shí)間,取不到時(shí)返回null
                  5)take():取走BlockingQueue里排在首位的對(duì)象,若BlockingQueue為空,阻斷進(jìn)入等待狀態(tài)直到Blocking有新的對(duì)象被加入為止
              2.BlockingQueue有四個(gè)具體的實(shí)現(xiàn)類,根據(jù)不同需求,選擇不同的實(shí)現(xiàn)類
                  1)ArrayBlockingQueue:規(guī)定大小的BlockingQueue,其構(gòu)造函數(shù)必須帶一個(gè)int參數(shù)來(lái)指明其大小.其所含的對(duì)象是以FIFO(先入先出)順序排序的.
                  2)LinkedBlockingQueue:大小不定的BlockingQueue,若其構(gòu)造函數(shù)帶一個(gè)規(guī)定大小的參數(shù),生成的BlockingQueue有大小限制,若不帶大小參數(shù),所生成的BlockingQueue的大小由Integer.MAX_VALUE來(lái)決定.其所含的對(duì)象是以FIFO(先入先出)順序排序的
                  3)PriorityBlockingQueue:類似于LinkedBlockQueue,但其所含對(duì)象的排序不是FIFO,而是依據(jù)對(duì)象的自然排序順序或者是構(gòu)造函數(shù)的Comparator決定的順序.
                  4)SynchronousQueue:特殊的BlockingQueue,對(duì)其的操作必須是放和取交替完成的.
              3.LinkedBlockingQueue和ArrayBlockingQueue比較起來(lái),它們背后所用的數(shù)據(jù)結(jié)構(gòu)不一樣,導(dǎo)致LinkedBlockingQueue的數(shù)據(jù)吞吐量要大于ArrayBlockingQueue,但在線程數(shù)量很大時(shí)其性能的可預(yù)見性低于ArrayBlockingQueue.         
           
          */
          public class BlockingQueueTest {
                 /**定義裝蘋果的籃子*/
                 public static class Basket{
                        //籃子,能夠容納3個(gè)蘋果
                        BlockingQueue<String> basket = new ArrayBlockingQueue<String>(3);
                        //生產(chǎn)蘋果,放入籃子
                        public void produce() throws InterruptedException{
                               //put方法放入一個(gè)蘋果,若basket滿了,等到basket有位置
                               basket.put("An apple");
                        }
                        //消費(fèi)蘋果,從籃子中取走
                        public String consume() throws InterruptedException{
                               //take方法取出一個(gè)蘋果,若basket為空,等到basket有蘋果為止
                               return basket.take();
                        }
                 }
                 //測(cè)試方法
                 public static void testBasket(){
                        final Basket basket = new Basket();//建立一個(gè)裝蘋果的籃子
                        
          //定義蘋果生產(chǎn)者
                        class Producer implements Runnable{
                               public void run(){
                                      try{
                                             while(true){
                                                    //生產(chǎn)蘋果
                                                    System.out.println("生產(chǎn)者準(zhǔn)備生產(chǎn)蘋果: " + System.currentTimeMillis());
                                                    basket.produce();
                                                    System.out.println("生產(chǎn)者生產(chǎn)蘋果完畢: " + System.currentTimeMillis());
                                                    //休眠300ms
                                                    Thread.sleep(300);
                                             }
                                      }catch(InterruptedException ex){
                                      }
                               }
                        }
                        //定義蘋果消費(fèi)者
                        class Consumer implements Runnable{
                               public void run(){
                                      try{
                                             while(true){
                                                    //消費(fèi)蘋果
                                                    System.out.println("消費(fèi)者準(zhǔn)備消費(fèi)蘋果: " + System.currentTimeMillis());
                                                    basket.consume();
                                                    System.out.println("消費(fèi)者消費(fèi)蘋果完畢: " + System.currentTimeMillis());
                                                    //休眠1000ms
                                                    Thread.sleep(1000);
                                             }
                                      }catch(InterruptedException ex){
                                      }
                               }
                        }
                        ExecutorService service = Executors.newCachedThreadPool();
                        Producer producer = new Producer();
                        Consumer consumer = new Consumer();
                        service.submit(producer);
                        service.submit(consumer);
                        //程序運(yùn)行5s后,所有任務(wù)停止
                        try{
                               Thread.sleep(5000);
                        }catch(InterruptedException ex){
                        }
                        service.shutdownNow();
                 }
                 public static void main(String[] args){
                        BlockingQueueTest.testBasket();
                 }
          }
          posted on 2012-01-06 16:32 RoyPayne 閱讀(235) 評(píng)論(0)  編輯  收藏 所屬分類: java并發(fā)
          主站蜘蛛池模板: 五家渠市| 十堰市| 北宁市| 镇坪县| 鹤岗市| 石景山区| 汉阴县| 乡宁县| 牙克石市| 阿勒泰市| 辉南县| 金昌市| 蕉岭县| 广丰县| 锡林郭勒盟| 灯塔市| 温宿县| 当阳市| 门源| 桐梓县| 抚州市| 勐海县| 鸡东县| 布拖县| 白河县| 山西省| 平度市| 南宁市| 南丹县| 大港区| 辛集市| 永和县| 南和县| 信丰县| 洞头县| 南昌县| 营口市| 靖边县| 阿坝县| 凤凰县| 辉南县|