Queue是JDK 5以后引入的新的集合類,它屬于Java Collections Framework的成員,在Collection集合中和List/Set是同一級(jí)別的接口。通常來(lái)講Queue描述的是一種FIFO的隊(duì)列,當(dāng)然不全都是,比如PriorityQueue是按照優(yōu)先級(jí)的順序(或者說(shuō)是自然順序,借助于Comparator接口)。
下圖描述了Java Collections Framework中Queue的整個(gè)家族體系。
對(duì)于Queue而言是在Collection的基礎(chǔ)上增加了offer/remove/poll/element/peek方法,另外重新定義了add方法。對(duì)于這六個(gè)方法,有不同的定義。
|
拋出異常
|
返回特殊值
|
操作描述
|
插入
|
add(e)
|
offer(e)
|
將元素加入到隊(duì)列尾部
|
移除
|
remove()
|
poll()
|
移除隊(duì)列頭部的元素
|
檢查
|
element()
|
peek()
|
返回隊(duì)列頭部的元素而不移除此元素
|
特別說(shuō)明的是對(duì)于Queue而言,規(guī)范并沒(méi)有規(guī)定是線程安全的,為了解決這個(gè)問(wèn)題,引入了可阻塞的隊(duì)列BlockingQueue。對(duì)于BlockingQueue而言所有操作的是線程安全的,并且隊(duì)列的操作可以被阻塞,直到滿足某種條件。Queue的另一個(gè)子接口Deque描述的是一個(gè)雙向的隊(duì)列。與Queue不同的是,Deque允許在隊(duì)列的頭部增加元素和在隊(duì)列的尾部刪除元素。也就是說(shuō)Deque是一個(gè)雙向隊(duì)列。二者功能都有的隊(duì)列就是BlockingDeque,這種阻塞隊(duì)列允許在隊(duì)列的頭和尾部分別操作元素,應(yīng)該說(shuō)是Queue中功能最強(qiáng)大的實(shí)現(xiàn)。
在JDK 5之前LinkedList就已經(jīng)存在,而且本身實(shí)現(xiàn)都是一種雙向隊(duì)列。所以到了JDK 5以后就將LinkedList同時(shí)實(shí)現(xiàn)Deque接口,這樣LinkedList就又屬于Queue的一部分了。
通常情況下Queue都是靠鏈表結(jié)構(gòu)實(shí)現(xiàn)的,但是鏈表意味著有一些而外的引用開(kāi)銷,如果是雙向鏈表開(kāi)銷就更大了。所以為了節(jié)省內(nèi)存,一種方式就是使用固定大小的數(shù)組來(lái)實(shí)現(xiàn)隊(duì)列。在這種情況下隊(duì)列的大小是固定,元素的遍歷通過(guò)數(shù)組的索引進(jìn)行,很顯然這是一種雙向鏈表的模型。ArrayDeque就是這樣一種實(shí)現(xiàn)。
另外ArrayBlockingQueue也是一種數(shù)組實(shí)現(xiàn)的隊(duì)列,但是卻沒(méi)有改造成雙向,僅僅實(shí)現(xiàn)了BlockingQueue的模型。理論上和ArrayDeque一樣也應(yīng)該容易改造成雙向的實(shí)現(xiàn)。
PriorityQueue和PriorityBlockingQueue實(shí)現(xiàn)了一種排序的隊(duì)列模型。這很類似與SortedSet,通過(guò)隊(duì)列的Comparator接口或者Comparable元素來(lái)排序元素。這種情況下元素在隊(duì)列中的出入就不是按照FIFO的形式,而是根據(jù)比較后的自然順序來(lái)進(jìn)行。
CocurrentLinkedQueue是一種線程安全卻非阻塞的FIFO隊(duì)列,這種隊(duì)列通常實(shí)現(xiàn)起來(lái)比較簡(jiǎn)單,但是卻很有效。在接下來(lái)的章節(jié)會(huì)詳細(xì)的描述它。
SynchronousQueue是一種特別的BlockingQueue,它只是把一個(gè)add/offer操作的元素直接移交給remove/take操作。也就是說(shuō)它本身不會(huì)緩存任何元素,所以嚴(yán)格意義上說(shuō)來(lái)講并不是一種真正的隊(duì)列。此隊(duì)列維護(hù)一個(gè)線程列表,這些線程等待從隊(duì)列中加入元素或者移除元素。簡(jiǎn)單的說(shuō),至少有一個(gè)remove/take操作時(shí)add/offer操作才能成功,同樣至少有一個(gè)add/offer操作時(shí)remove/take操作才能成功。這是一種雙向等待的隊(duì)列模型,出隊(duì)列等待加入等列,而入隊(duì)列又等待出隊(duì)列。這種隊(duì)列的好處在于能夠最大線程的保持吞吐量卻又是線程安全的。所以對(duì)于一個(gè)需要快速處理的任務(wù)隊(duì)列,SynchronousQueue是一個(gè)不錯(cuò)的選擇。
BlockingQueue還有一種實(shí)現(xiàn)DelayQueue,這種實(shí)現(xiàn)允許每一個(gè)元素(Delayed)帶有一個(gè)延時(shí)時(shí)間,當(dāng)調(diào)用take/poll的時(shí)候會(huì)檢測(cè)隊(duì)列頭元素這個(gè)時(shí)間是否<=0,如果滿足就是說(shuō)已經(jīng)超時(shí)了,那么此元素就可以被移除了,否則就會(huì)等待。特別說(shuō)明的是這個(gè)頭元素應(yīng)該是最先被超時(shí)的元素(這個(gè)時(shí)間是絕對(duì)時(shí)間)。這個(gè)類設(shè)計(jì)很巧妙,被用于ScheduledFutureTask來(lái)進(jìn)行定時(shí)操作。希望后面會(huì)開(kāi)辟一個(gè)章節(jié)講講這里面的想法。實(shí)在不行在講線程池部分肯定會(huì)提到這個(gè)。
©2009-2014 IMXYLZ
|求賢若渴