線程池都有哪幾種工做隊列

http://www.javashuo.com/article/p-mfnluzjn-ca.htmlhtml

一、ArrayBlockingQueue
是一個基於數組結構的有界阻塞隊列,此隊列按 FIFO(先進先出)原則對元素進行排序。數組

  • ArrayBlockingQueue在生產者放入數據和消費者獲取數據,都是共用同一個鎖對象,
    • 由此也意味着二者沒法真正並行運行
    • 這點尤爲不一樣於LinkedBlockingQueue

二、LinkedBlockingQueue
一個基於鏈表結構的阻塞隊列,此隊列按FIFO (先進先出) 排序元素,吞吐量一般要高於ArrayBlockingQueue。線程

  • 靜態工廠方法Executors.newFixedThreadPool()使用了這個隊列

三、SynchronousQueue
一個不存儲元素的阻塞隊列htm

  • 每一個插入操做必須等到另外一個線程調用移除操做,不然插入操做一直處於阻塞狀態,
  • 吞吐量一般要高於LinkedBlockingQueue,
  • 靜態工廠方法Executors.newCachedThreadPool(5)使用了這個隊列。

四、PriorityBlockingQueue對象

  • 一個具備優先級的無限阻塞隊列
  • PriorityBlockingQueue也是基於最小二叉堆實現
    • 數組實現的最小堆
    • 使用基於CAS實現的自旋鎖來控制隊列的動態擴容,
    • 保證了擴容操做不會阻塞take操做的執行
      • 不擴容就是正常的獲取鎖以後加入元素
      • PriorityBlockingQueue擴容時,
        • 由於增長堆數組的長度並不影響隊列中元素的出隊操做,
        • 於是使用自旋CAS操做實現的鎖來控制擴容操做,
        • 僅在數組引用替換拷貝元素時才加鎖,
        • 從而減小了擴容對出隊操做的影響

DelayQueueblog

  • 只有當其指定的延遲時間到了,纔可以從隊列中獲取到該元素。
  • DelayQueue是一個沒有大小限制的隊列,
  • 所以往隊列中插入數據的操做(生產者)永遠不會被阻塞,而只有獲取數據的操做(消費者)纔會被阻塞。
  • 使用場景:
    • elayQueue使用場景較少,但都至關巧妙,
    • 常見的例子好比使用一個DelayQueue來管理一個超時未響應的鏈接隊列。
相關文章
相關標籤/搜索