java.util.concurrent.BlockingQueue ArrayBlockingQueue

來源:互聯網
上載者:User

 

一、簡介

    BlockingQueue介面定義了一種阻塞的FIFO queue,每一個BlockingQueue都有一個容量,讓容量滿時往BlockingQueue中添加資料時會造成阻塞,當容量為空白時取元素操作會阻塞。ArrayBlockingQueue是對BlockingQueue的一個數組實現,它使用一把全域的鎖並行對queue的讀寫操作,同時使用兩個Condition阻塞容量為空白時的取操作和容量滿時的寫操作。

二、具體實現

    ArrayBlockingQueue底層定義如下:

public class ArrayBlockingQueue<E> extends AbstractQueue<E>           implements BlockingQueue<E>, java.io.Serializable {         // 使用迴圈數組來實現queue,初始時takeIndex和putIndex均為0       private final E[] items;       private transient int takeIndex;       private transient int putIndex;       private int count;         // 用於並發的鎖和條件      private final ReentrantLock lock;       private final Condition notEmpty;       private final Condition notFull;         /**       * 迴圈數組       * Circularly increment i.       */      final int inc(int i) {           return (++i == items.length)? 0 : i;       }         public ArrayBlockingQueue(int capacity, boolean fair) {           if (capacity <= 0)               throw new IllegalArgumentException();           this.items = (E[]) new Object[capacity];           // 分配鎖及該鎖上的condition           lock = new ReentrantLock(fair);           notEmpty = lock.newCondition();           notFull =  lock.newCondition();       }       ...   }  

ArrayBlockingQueue的取操作:

public class ArrayBlockingQueue<E> extends AbstractQueue<E>           implements BlockingQueue<E>, java.io.Serializable {         private E extract() {           final E[] items = this.items;           E x = items[takeIndex];           items[takeIndex] = null;           takeIndex = inc(takeIndex);           --count;          // 激發notFull條件           notFull.signal();           return x;       }          /**          * condition的await的語義如下:       * 與condition相關的鎖以原子方式釋放,並禁用該線程       * 方法返回時,線程必須獲得與該condition相關的鎖       */      public E take() throws InterruptedException {           final ReentrantLock lock = this.lock;           lock.lockInterruptibly();           try {               try {                     // 等待notEmpty的條件                   while (count == 0)                       notEmpty.await();               } catch (InterruptedException ie) {                   notEmpty.signal(); // propagate to non-interrupted thread                   throw ie;               }               E x = extract();               return x;           } finally {               lock.unlock();           }       }       ...   }  

ArrayBlockingQueue的寫操作:

public class ArrayBlockingQueue<E> extends AbstractQueue<E>           implements BlockingQueue<E>, java.io.Serializable {         private void insert(E x) {           items[putIndex] = x;           putIndex = inc(putIndex);           ++count;           notEmpty.signal();       }         public void put(E o) throws InterruptedException {           if (o == null) throw new NullPointerException();           final E[] items = this.items;           final ReentrantLock lock = this.lock;           lock.lockInterruptibly();           try {               try {                     // 等待notFull條件              while (count == items.length)                       notFull.await();               } catch (InterruptedException ie) {                   notFull.signal(); // propagate to non-interrupted thread                   throw ie;               }               insert(o);           } finally {               lock.unlock();           }       }       ...   }  

注意:ArrayBlockingQueue在讀寫操作上都需要鎖住整個容器,因此輸送量與一般的實現是相似的,適合於實現“生產者消費者”模式。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.