線程小酌之JAVA中的阻塞隊列__JAVA

來源:互聯網
上載者:User

       最近在學習java中內建的JDK並發包,java.util.concurrent,發現功能很強大,其中之一就是工作中多次用到的線程工具類BlockingQueue。在實際開發工作和面試過程中,經常會考察對於該工具類的使用和理解。

1. 什麼是阻塞隊列。 阻塞隊列(BlockingQueue)是一個支援兩個附加操作的隊列。這兩個附加的操作是:在隊列為空白時,擷取元素的線程會等待隊列變為非空。當隊列滿時,儲存元素的線程會等待隊列可用。阻塞隊列常用於生產者和消費者的情境,生產者是往隊列裡添加元素的線程,消費者是從隊列裡拿元素的線程。阻塞隊列就是生產者存放元素的容器,而消費者也只從容器裡拿元素。

2.詳解BlockingQueue


BlockingQueue最終會有四種狀況,拋出異常、返回特殊值、阻塞、逾時,下表總結了這些方法:


  拋出異常 特殊值 阻塞 逾時
插入 add(e) offer(e) put(e) offer(e, time, unit)
移除 remove() poll() take() poll(time, unit)
檢查 element() peek() 不可用 不可用


       BlockingQueue是個介面,有如下實作類別:

       1. ArrayBlockQueue:一個由數組支援的有界阻塞隊列。此隊列按 FIFO(先進先出)原則對元素進行排序。建立其對象必須明確大小,像數組一樣。

       2. LinkedBlockQueue:一個可改變大小的阻塞隊列。此隊列按 FIFO(先進先出)原則對元素進行排序。建立其對象如果沒有明確大小,預設值是Integer.MAX_VALUE。連結隊列的輸送量通常要高於基於數組的隊列,但是在大多數並發應用程式中,其可預知的效能要低。 

       3. PriorityBlockingQueue:類似於LinkedBlockingQueue,但其所含對象的排序不是FIFO,而是依據對象的自然排序次序或者是建構函式所帶的Comparator決定的順序。

       4. SynchronousQueue:同步隊列。同步隊列沒有任何容量,每個插入必須等待另一個線程移除,反之亦然。


由於LinkedBlockingQueue實現是安全執行緒的,實現了先進先出等特性,是作為生產者消費者的首選,LinkedBlockingQueue 可以指定容量,也可以不指定,不指定的話,預設最大是Integer.MAX_VALUE,其中主要用到put和take方法,put方法在隊列滿的時候會阻塞直到有隊列成員被消費,take方法在隊列空的時候會阻塞,直到有隊列成員被放進來。

package cn.thread;import java.util.concurrent.BlockingQueue;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.LinkedBlockingQueue;/** * 多線程類比實現生產者/消費者模型 *   */public class BlockingQueueTest2 {    /**     *      * 定義裝蘋果的籃子     *      */    public class Basket {        // 籃子,能夠容納3個蘋果        BlockingQueue<String> basket = new LinkedBlockingQueue<String>(3);        // 生產蘋果,放入籃子        public void produce() throws InterruptedException {            // put方法放入一個蘋果,若basket滿了,等到basket有位置            basket.put("An apple");        }        // 消費蘋果,從籃子中取走        public String consume() throws InterruptedException {            // take方法取出一個蘋果,若basket為空白,等到basket有蘋果為止(擷取並移除此隊列的頭部)            return basket.take();        }    }    // 定義蘋果生產者    class Producer implements Runnable {        private String instance;        private Basket basket;        public Producer(String instance, Basket basket) {            this.instance = instance;            this.basket = basket;        }        public void run() {            try {                while (true) {                    // 生產蘋果                    System.out.println("生產者準備生產蘋果:" + instance);                    basket.produce();                    System.out.println("!生產者生產蘋果完畢:" + instance);                    // 休眠300ms                    Thread.sleep(300);                }            } catch (InterruptedException ex) {                System.out.println("Producer Interrupted");            }        }    }    // 定義蘋果消費者    class Consumer implements Runnable {        private String instance;        private Basket basket;        public Consumer(String instance, Basket basket) {            this.instance = instance;            this.basket = basket;        }        public void run() {            try {                while (true) {                    // 消費蘋果                    System.out.println("消費者準備消費蘋果:" + instance);                    System.out.println(basket.consume());                    System.out.println("!消費者消費蘋果完畢:" + instance);                    // 休眠1000ms                    Thread.sleep(1000);                }            } catch (InterruptedException ex) {                System.out.println("Consumer Interrupted");            }        }    }    public static void main(String[] args) {        BlockingQueueTest2 test = new BlockingQueueTest2();        // 建立一個裝蘋果的籃子        Basket basket = test.new Basket();        ExecutorService service = Executors.newCachedThreadPool();        Producer producer = test.new Producer("生產者001", basket);        Producer producer2 = test.new Producer("生產者002", basket);        Consumer consumer = test.new Consumer("消費者001", basket);        service.submit(producer);        service.submit(producer2);        service.submit(consumer);        // 程式運行5s後,所有任務停止//        try {//            Thread.sleep(1000 * 5);//        } catch (InterruptedException e) {//            e.printStackTrace();//        }//        service.shutdownNow();    }}





聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.