Java隊列總結
通過前面文章的學習,我們對Java中常用隊列做了介紹。本文,咱們來對隊列做個總結吧。
首先,我們介紹了現實生活中的實際場景(排隊買票等),來告訴我們為什麼需要使用隊列。
隊列是一種先進先出(FIFO)的抽象數據結構,在Java中,隊列使用了兩種數據類型來實現的,分別是:數組和鍊表這兩種數據結構。
本文主要內容:回顧Java中常用的七個阻塞隊列進行總結及阻塞隊列中四組AP並進行總結。
本文來源:本文是由凱哥Java(kaigejava)原創發布。
接著,我們介紹了隊列的分類,可以分為兩類,即阻塞隊列和非阻塞隊列。
常用的三個非阻塞隊列:LinkedList、PriorityQueue和ConcurrentLinkedQueue.
(PS:凱哥沒有做介紹,在以後的文章中,凱哥將對ConcurrentLinkedQueue進行介紹)
然後我們介紹Java中常用的七個阻塞隊列。他們之間類圖關係:
我們可以看到,隊列是Collection的子類。也即和arrayList類似的。
接著我們就對七個阻塞隊列做了詳細的介紹。
阻塞隊列的七個子類
ArrayBlockingQueue(下文簡稱:ABQueue)、LinkedBlockingQueue(下文簡稱:LBQueue)、PriorityBlockingQueue(下文簡稱:PBQueue)、DelayQueue(下文簡稱:DQueue)、SynchronouseQueue(下文簡稱:SyncQueue)、LinkedTrnsferQueue(下文簡稱:LTQueue)、LinkedBlockingDeque(下文簡稱:LBDeque)這個七個。
來分別說說每個隊列的特點:
ABQueue:
底層使用的是數組結構。因為數組需要初始化大小,所以其構造器需要輸入隊列的大小。
是有界的阻塞安全隊列(思考:為什麼說是有界的?是怎麼保證線程安全的?),默認是不保證線程的公平性(思考:為什麼默認不能保證線程公平?如何保證線程安全?),不允許向隊列中插入null元素。
LBQueue:
「有界」的阻塞安全隊列,其底層使用的是鍊表的數據結構。所謂的「有界」是因為,默認隊列的大小是Integer.MAX_VALUE。這個數值等於21億+。因為這個數據太大了,也可以理解為無界的。不建議使用默認值,最好在初始化的時候,指定隊列的大小。
PBQueue:
是一個支持優先級的無界隊列。支持優先級是因為使用了comparator這個接口。默認採用字典升序排序策略的。如果不想使用默認的,在初始化的時候,還可以自定義比較器的。
以上三個隊列相關更詳細的介紹,歡迎回看《Java中常用的七個阻塞隊列介紹第一篇》。在這篇文章中,凱哥對這三個隊列做了詳細的介紹以及代碼演示。
DQueue:
是一個支持優先級的無界阻塞隊列。支持優先級是應該底層使用的是PriorityQueue隊列來實現的。而PriorityQueue隊列在添加元素的時候使用了siftUpComparable方法。這個對了的一個特點:支持延時獲取。所以,這個隊列可以運用在緩存系統的設計中。當從隊列中獲取到數據,說明延時時間到了。
關於DQueue更多詳細的介紹,歡迎回看:《Java中常用的七個阻塞隊列第二篇DelayQueue源碼介紹》。在這篇文章中,凱哥做了詳細的介紹,同時使用代碼模擬了緩存數據到期操作。
SyncQueue:
是一個無存儲空間的阻塞同步隊列。不存儲元素的原因是因為,一個put操作必須等待一個take操作與之對應才可以。否則就不能繼續添加元素了。默認使用非公平的。在性能上SyncQueue隊列的吞吐量比LBqueu和ABQueue的性能高。
LTQueue:是由鍊表組成的無界隊列。比其他隊列多了兩個方法:tryTransfer、transfer
LBDeque:鍊表組成的雙端隊列。這個隊列在以後凱哥講For/Join框架的時候,還會說到。
七個阻塞隊列的小總結:
接著,我們講解了隊列中常用的四組API。
阻塞隊列四組API
會拋異常的:添加元素使用add(e),刪除元素使用remove,檢查隊首元素使用的element.
當隊列滿的時候,在向隊列中添加元素會拋出異常;當隊列為空的時候在從隊列中刪除或者是獲取隊首元素都會拋出異常;
帶有返回值的:添加元素:offer(e),刪除元素:poll(),檢查隊首元素:peek().
當隊列滿的時候,再調用offer(e)向隊列中添加元素會返回false而不是拋出異常
當隊列為空的時候,調用take()或者是peek()方法返回null而不是拋出異常
阻塞一直等待的:添加元素:put(e),刪除元素:take()
當隊列滿的時候,再向隊列中添加元素,隊列會進入阻塞狀態,直到元素添加成功為止。
當隊列為空的時候,再從隊列刪除元素,隊列會阻塞,直到能夠刪除元素為止。
帶有超時時間的阻塞:添加元素:offer(e,time,unit),刪除元素:poll(time,unit)
當隊列滿的時候,調用offer(e,time,unit)會進入阻塞等待中,當過來超時時間,退出等待
當隊列為空的時候,調用poll(time,unit)方法會進入等待狀態,當到了超時時間,會退出等待。
四組API總結:
關於四組API更詳細的介紹歡迎學習:《Java阻塞隊列的四組API》。在這篇文章中凱哥做了詳細的介紹。用人的一生四個階段來比擬這四組API。
到此,我們已經把Java中隊列介紹完畢。接下來,凱哥將帶著大家一起學習線程池。歡迎大家繼續學習。