java.util.concurrent.LinkedBlockingQueue

來源:互聯網
上載者:User
一、簡介

    LinkedBlockingQueue是BlockingQueue的一種使用Link List的實現,它對頭和尾(取和添加操作)採用兩把不同的鎖,相對於ArrayBlockingQueue提高了輸送量。它也是一種阻塞型的容器,適合於實現“消費者生產者”模式。

二、具體實現

    LinkedBlockingQueue底層的定義如下:

public class LinkedBlockingQueue<E> extends AbstractQueue<E>           implements BlockingQueue<E>, java.io.Serializable {         static class Node<E> {           /** The item, volatile to ensure barrier separating write and read */          volatile E item;           Node<E> next;           Node(E x) { item = x; }       }         // 支援原子操作        private final AtomicInteger count = new AtomicInteger(0);         // 鏈表的頭和尾        private transient Node<E> head;       private transient Node<E> last;         // 針對取和添加操作的兩把鎖及其上的條件       private final ReentrantLock takeLock = new ReentrantLock();       private final Condition notEmpty = takeLock.newCondition();       private final ReentrantLock putLock = new ReentrantLock();       private final Condition notFull = putLock.newCondition();        ...   }  

LinkedBlockingQueue的添加操作:

 

public class LinkedBlockingQueue<E> extends AbstractQueue<E>           implements BlockingQueue<E>, java.io.Serializable {         private void insert(E x) {           last = last.next = new Node<E>(x);       }         /**       * signal方法在被調用時,當前線程必須擁有該condition相關的鎖!       * Signal a waiting take. Called only from put/offer (which do not       * otherwise ordinarily lock takeLock.)       */      private void signalNotEmpty() {           final ReentrantLock takeLock = this.takeLock;           takeLock.lock();           try {               notEmpty.signal();           } finally {               takeLock.unlock();           }       }         public void put(E o) throws InterruptedException {           if (o == null) throw new NullPointerException();           int c = -1;           final ReentrantLock putLock = this.putLock;           final AtomicInteger count = this.count;           // 使用putLock           putLock.lockInterruptibly();           try {               try {                     // 當容量已滿時,等待notFull條件               while (count.get() == capacity)                       notFull.await();               } catch (InterruptedException ie) {                   notFull.signal(); // propagate to a non-interrupted thread                   throw ie;               }               insert(o);               // 取出當前值,並將原資料增加1               c = count.getAndIncrement();               // 容量不滿,再次啟用notFull上等待的put線程           if (c + 1 < capacity)                   notFull.signal();           } finally {               putLock.unlock();           }           // 必須先釋放putLock再在notEmpty上signal,否則會造成死結        if (c == 0)               signalNotEmpty();       }       ...   }  

LinkedBlockingQueue的取操作:

public class LinkedBlockingQueue<E> extends AbstractQueue<E>           implements BlockingQueue<E>, java.io.Serializable {         private E extract() {           Node<E> first = head.next;           head = first;           E x = first.item;           first.item = null;           return x;       }         private void signalNotFull() {           final ReentrantLock putLock = this.putLock;           putLock.lock();           try {               notFull.signal();           } finally {               putLock.unlock();           }       }         public E take() throws InterruptedException {           E x;           int c = -1;           final AtomicInteger count = this.count;           final ReentrantLock takeLock = this.takeLock;           // 使用takeLock           takeLock.lockInterruptibly();           try {               try {                     // 若容量為空白,等待notEmpty                   while (count.get() == 0)                       notEmpty.await();               } catch (InterruptedException ie) {                   notEmpty.signal(); // propagate to a non-interrupted thread                   throw ie;               }                 x = extract();               c = count.getAndDecrement();               // 再次啟用notEmpty               if (c > 1)                   notEmpty.signal();           } finally {               takeLock.unlock();           }           // take執行之前容量已滿,則啟用notFull           if (c == capacity)               signalNotFull();           return x;       }       ...   }  

 

    ConcurrentLinkedQueue是一個無鎖的queue實現,它採用了一種無鎖演算法(在API中有說明),相比於傳統的同步的queue來說輸送量可以大大提高,同時它也不同於BlockingQueue,並不單單提供阻塞操作。它主要的目的是通過採用無鎖的演算法,使得read/write操作均不需要對容器加鎖,提高容器輸送量

相關文章

聯繫我們

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