天天看點

Java中常用隊列的總結

Java隊列總結

通過前面文章的學習,我們對Java中常用隊列做了介紹。本文,咱們來對隊列做個總結吧。

首先,我們介紹了現實生活中的實際場景(排隊買票等),來告訴我們為什麼需要使用隊列。

隊列是一種先進先出(FIFO)的抽象資料結構,在Java中,隊列使用了兩種資料類型來實作的,分别是:數組和連結清單這兩種資料結構。

本文主要内容:回顧Java中常用的七個阻塞隊列進行總結及阻塞隊列中四組AP并進行總結。

本文來源:本文是由凱哥Java(kaigejava)原創釋出。

接着,我們介紹了隊列的分類,可以分為兩類,即阻塞隊列和非阻塞隊列。

常用的三個非阻塞隊列:LinkedList、PriorityQueue和ConcurrentLinkedQueue.

(PS:凱哥沒有做介紹,在以後的文章中,凱哥将對ConcurrentLinkedQueue進行介紹)

然後我們介紹Java中常用的七個阻塞隊列。他們之間類圖關系:

Java中常用隊列的總結

我們可以看到,隊列是Collection的子類。也即和arrayList類似的。

接着我們就對七個阻塞隊列做了詳細的介紹。

阻塞隊列的七個子類

ArrayBlockingQueue(下文簡稱:ABQueue)、LinkedBlockingQueue(下文簡稱:LBQueue)、PriorityBlockingQueue(下文簡稱:PBQueue)、DelayQueue(下文簡稱:DQueue)、SynchronouseQueue(下文簡稱:SyncQueue)、LinkedTrnsferQueue(下文簡稱:LTQueue)、LinkedBlockingDeque(下文簡稱:LBDeque)這個七個。

Java中常用隊列的總結

來分别說說每個隊列的特點:

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架構的時候,還會說到。

七個阻塞隊列的小總結:

Java中常用隊列的總結

接着,我們講解了隊列中常用的四組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總結:

Java中常用隊列的總結

關于四組API更詳細的介紹歡迎學習:《Java阻塞隊列的四組API》。在這篇文章中凱哥做了詳細的介紹。用人的一生四個階段來比拟這四組API。

到此,我們已經把Java中隊列介紹完畢。接下來,凱哥将帶着大家一起學習線程池。歡迎大家繼續學習

想要學習Java開發的同學,可以參考成都Java教育訓練班提供的學習大綱;