runnableTaskQueue(任務隊列):用于保存等待執行的任務的阻塞隊列。 可以選擇以下幾個阻塞隊列:
BlockingQueue的幾個注意點
【1】BlockingQueue 可以是限定容量的。它在任意給定時間都可以有一個remainingCapacity,超出此容量,便無法無阻塞地put 附加元素。沒有任何內部容量約束的BlockingQueue 總是報告Integer.MAX_VALUE 的剩余容量。
【2】BlockingQueue 實現主要用于生產者-使用者隊列,但它另外還支持Collection 接口。
【3】BlockingQueue 實現是線程安全的。
【4】BlockingQueue 實質上不 支持使用任何一種“close”或“shutdown”操作來指示不再添加任何項。
1)ArrayBlockingQueue:規定大小的BlockingQueue,其構造函數必須帶一個int參數來指明其大小.其所含的對象是以FIFO(先入先出)順序排序的.
1:它是有界阻塞隊列。它是數組實現的,是一個典型的“有界緩存區”。數組大小在構造函數指定,而且從此以后不可改變。
2:是它線程安全的,是阻塞的,具體參考BlockingQueue的“注意4”。
3:不接受?null?元素
4:公平性?(fairness)可以在構造函數中指定。如果為true,則按照 FIFO 順序訪問插入或移除時受阻塞線程的隊列;如果為 false,則訪問順序是不確定的。
5:它實現了BlockingQueue接口。關于BlockingQueue,請參照《BlockingQueue》
6:此類及其迭代器實現了?Collection?和?Iterator?接口的所有可選?方法。
7:其容量在構造函數中指定。容量不可以自動擴展,也沒提供手動擴展的接口。
8:在JDK5/6中,LinkedBlockingQueue和ArrayBlocingQueue等對象的poll(long?timeout,?TimeUnit?unit)存在內存泄露Leak的對象是AbstractQueuedSynchronizer.Node,
2)LinkedBlockingQueue:大小不定的BlockingQueue,若其構造函數帶一個規定大小的參數,生成的BlockingQueue有大小限制,若不帶大小參數,所生成的BlockingQueue的大小由Integer.MAX_VALUE來決定.其所含的對象是以FIFO(先入先出)順序排序的
并發庫中的BlockingQueue是一個比較好玩的類,顧名思義,就是阻塞隊列。該類主要提供了兩個方法put()和take(),前者將一個對象放到隊列中,如果隊列已經滿了,就等待直到有空閑節點;后者從head取一個對象,如果沒有對象,就等待直到有可取的對象。
3)PriorityBlockingQueue:類似于LinkedBlockQueue,但其所含對象的排序不是FIFO,而是依據對象的自然排序順序或者是構造函數的Comparator決定的順序.
1:它是無界阻塞隊列,容量是無限的,它使用與類PriorityQueue相同的順序規則。
2:它是線程安全的,是阻塞的
3:不允許使用?null?元素。
4:對于put(E?o)和offer(E?o,?long?timeout,?TimeUnit?unit),由于該隊列是無界的,所以此方法永遠不會阻塞。因此參數timeout和unit沒意義,會被忽略掉。
5:iterator()?方法中所提供的迭代器并不保證以特定的順序遍歷?PriorityBlockingQueue?的元素。
如果需要有序地遍歷,則應考慮使用?Arrays.sort(pq.toArray())。
6.至于使用和別的BlockingQueue(ArrayBlockingQueue,LinkedBlockingQueue)相似,可以參照它們。7:此類及其迭代器實現了?Collection?和?Iterator?接口的所有可選?方法。
4)SynchronousQueue:特殊的BlockingQueue,對其的操作必須是放和取交替完成的.(每個插入操作必須等到另一個線程調用移除操作,否則插入操作一直處于阻塞狀態,)此隊列不允許 null 元素。
SynchronousQueue的定義如下
public classSynchronousQueueextendsAbstractQueueimplementsBlockingQueue,Serializable
從上面可以看出,它實現BlockingQueue,所以是阻塞隊列,從名字看,它又是同步的。
它模擬的功能類似于生活中一手交錢一手交貨這種情形,像那種貨到付款或者先付款后發貨模型不適合使用SynchronousQueue。
首先要知道SynchronousQueue沒有容納元素的能力,即它的isEmpty()方法總是返回true
另外在創建SynchronousQueue時可以傳遞一個boolean參數來指定它是否是訪問它的線程按遵守FIFO順序處理,true表示遵守FIFO。
四種線程池各自的特點及所用到的隊列
newCachedThreadPool()緩存型池子,先查看池中有沒有以前建立的線程,如果有,就reuse.如果沒有,就建一個新的線程加入池中。能reuse的線程,必須是timeout IDLE內的池中線程,缺省timeout是60s,超過這個IDLE時長,線程實例將被終止及移出池。緩存型池子通常用于執行一些生存期很短的異步型任務 。所用隊列為SynchronousQueue()
newFixedThreadPool()fixedThreadPool與cacheThreadPool差不多,也是能reuse就用,但不能隨時建新的線程 其獨特之處:任意時間點,最多只能有固定數目的活動線程存在,此時如果有新的線程要建立,只能放在另外的隊列中等待,直到當前的線程中某個線程終止直接被移出池子。和cacheThreadPool不同:fixedThreadPool池線程數固定,但是0秒IDLE(無IDLE)。這也就意味著創建的線程會一直存在。所以fixedThreadPool多數針對一些很穩定很固定的正規并發線程,多用于服務器。所用隊列為LinkedBlockingQueue()
newScheduledThreadPool()調度型線程池。這個池子里的線程可以按schedule依次delay執行,或周期執行 。0秒IDLE(無IDLE)。所用隊列為DelayedWorkQueue()
newSingleThreadExecutor()單例線程,任意時間池中只能有一個線程 。用的是和cache池和fixed池相同的底層池,但線程數目是1-1,0秒IDLE(無IDLE)。所用隊列為LinkedBlockingQueue()