Java隊(duì)列總結(jié)
通過(guò)前面文章的學(xué)習(xí)宜肉,我們對(duì)Java中常用隊(duì)列做了介紹。本文翎碑,咱們來(lái)對(duì)隊(duì)列做個(gè)總結(jié)吧谬返。
首先,我們介紹了現(xiàn)實(shí)生活中的實(shí)際場(chǎng)景(排隊(duì)買票等)日杈,來(lái)告訴我們?yōu)槭裁葱枰褂藐?duì)列遣铝。
隊(duì)列是一種先進(jìn)先出(FIFO)的抽象數(shù)據(jù)結(jié)構(gòu)佑刷,在Java中,隊(duì)列使用了兩種數(shù)據(jù)類型來(lái)實(shí)現(xiàn)的酿炸,分別是:數(shù)組和鏈表這兩種數(shù)據(jù)結(jié)構(gòu)项乒。
本文主要內(nèi)容:回顧Java中常用的七個(gè)阻塞隊(duì)列進(jìn)行總結(jié)及阻塞隊(duì)列中四組AP并進(jìn)行總結(jié)。
本文來(lái)源:本文是由凱哥Java(kaigejava)原創(chuàng)發(fā)布梁沧。
接著檀何,我們介紹了隊(duì)列的分類,可以分為兩類廷支,即阻塞隊(duì)列和非阻塞隊(duì)列频鉴。
常用的三個(gè)非阻塞隊(duì)列:LinkedList、PriorityQueue和ConcurrentLinkedQueue.
(PS:凱哥沒(méi)有做介紹恋拍,在以后的文章中垛孔,凱哥將對(duì)ConcurrentLinkedQueue進(jìn)行介紹)
然后我們介紹Java中常用的七個(gè)阻塞隊(duì)列。他們之間類圖關(guān)系:
我們可以看到施敢,隊(duì)列是Collection的子類周荐。也即和arrayList類似的。
接著我們就對(duì)七個(gè)阻塞隊(duì)列做了詳細(xì)的介紹僵娃。
阻塞隊(duì)列的七個(gè)子類
ArrayBlockingQueue(下文簡(jiǎn)稱:ABQueue)概作、LinkedBlockingQueue(下文簡(jiǎn)稱:LBQueue)、PriorityBlockingQueue(下文簡(jiǎn)稱:PBQueue)默怨、DelayQueue(下文簡(jiǎn)稱:DQueue)讯榕、SynchronouseQueue(下文簡(jiǎn)稱:SyncQueue)、LinkedTrnsferQueue(下文簡(jiǎn)稱:LTQueue)匙睹、LinkedBlockingDeque(下文簡(jiǎn)稱:LBDeque)這個(gè)七個(gè)愚屁。
來(lái)分別說(shuō)說(shuō)每個(gè)隊(duì)列的特點(diǎn):
ABQueue:
底層使用的是數(shù)組結(jié)構(gòu)。因?yàn)閿?shù)組需要初始化大小痕檬,所以其構(gòu)造器需要輸入隊(duì)列的大小霎槐。
是有界的阻塞安全隊(duì)列(思考:為什么說(shuō)是有界的?是怎么保證線程安全的梦谜?)丘跌,默認(rèn)是不保證線程的公平性(思考:為什么默認(rèn)不能保證線程公平?如何保證線程安全改淑?)碍岔,不允許向隊(duì)列中插入null元素。
LBQueue:
“有界”的阻塞安全隊(duì)列朵夏,其底層使用的是鏈表的數(shù)據(jù)結(jié)構(gòu)蔼啦。所謂的“有界”是因?yàn)椋J(rèn)隊(duì)列的大小是Integer.MAX_VALUE仰猖。這個(gè)數(shù)值等于21億+捏肢。因?yàn)檫@個(gè)數(shù)據(jù)太大了奈籽,也可以理解為無(wú)界的。不建議使用默認(rèn)值鸵赫,最好在初始化的時(shí)候衣屏,指定隊(duì)列的大小。
PBQueue:
是一個(gè)支持優(yōu)先級(jí)的無(wú)界隊(duì)列辩棒。支持優(yōu)先級(jí)是因?yàn)槭褂昧薱omparator這個(gè)接口狼忱。默認(rèn)采用字典升序排序策略的。如果不想使用默認(rèn)的一睁,在初始化的時(shí)候钻弄,還可以自定義比較器的。
以上三個(gè)隊(duì)列相關(guān)更詳細(xì)的介紹者吁,歡迎回看《Java中常用的七個(gè)阻塞隊(duì)列介紹第一篇》窘俺。在這篇文章中,凱哥對(duì)這三個(gè)隊(duì)列做了詳細(xì)的介紹以及代碼演示复凳。
DQueue:
是一個(gè)支持優(yōu)先級(jí)的無(wú)界阻塞隊(duì)列瘤泪。支持優(yōu)先級(jí)是應(yīng)該底層使用的是PriorityQueue隊(duì)列來(lái)實(shí)現(xiàn)的。而PriorityQueue隊(duì)列在添加元素的時(shí)候使用了siftUpComparable方法育八。這個(gè)對(duì)了的一個(gè)特點(diǎn):支持延時(shí)獲取对途。所以,這個(gè)隊(duì)列可以運(yùn)用在緩存系統(tǒng)的設(shè)計(jì)中单鹿。當(dāng)從隊(duì)列中獲取到數(shù)據(jù)掀宋,說(shuō)明延時(shí)時(shí)間到了深纲。
關(guān)于DQueue更多詳細(xì)的介紹仲锄,歡迎回看:《Java中常用的七個(gè)阻塞隊(duì)列第二篇DelayQueue源碼介紹》。在這篇文章中湃鹊,凱哥做了詳細(xì)的介紹儒喊,同時(shí)使用代碼模擬了緩存數(shù)據(jù)到期操作。
SyncQueue:
是一個(gè)無(wú)存儲(chǔ)空間的阻塞同步隊(duì)列币呵。不存儲(chǔ)元素的原因是因?yàn)榛忱ⅲ粋€(gè)put操作必須等待一個(gè)take操作與之對(duì)應(yīng)才可以。否則就不能繼續(xù)添加元素了余赢。默認(rèn)使用非公平的芯义。在性能上SyncQueue隊(duì)列的吞吐量比LBqueu和ABQueue的性能高。
LTQueue:是由鏈表組成的無(wú)界隊(duì)列妻柒。比其他隊(duì)列多了兩個(gè)方法:tryTransfer扛拨、transfer
LBDeque:鏈表組成的雙端隊(duì)列。這個(gè)隊(duì)列在以后凱哥講For/Join框架的時(shí)候举塔,還會(huì)說(shuō)到绑警。
七個(gè)阻塞隊(duì)列的小總結(jié):
接著求泰,我們講解了隊(duì)列中常用的四組API。
阻塞隊(duì)列四組API
會(huì)拋異常的:添加元素使用add(e),刪除元素使用remove计盒,檢查隊(duì)首元素使用的element.
當(dāng)隊(duì)列滿的時(shí)候渴频,在向隊(duì)列中添加元素會(huì)拋出異常;當(dāng)隊(duì)列為空的時(shí)候在從隊(duì)列中刪除或者是獲取隊(duì)首元素都會(huì)拋出異常北启;
帶有返回值的:添加元素:offer(e),刪除元素:poll()卜朗,檢查隊(duì)首元素:peek().
當(dāng)隊(duì)列滿的時(shí)候,再調(diào)用offer(e)向隊(duì)列中添加元素會(huì)返回false而不是拋出異常
當(dāng)隊(duì)列為空的時(shí)候咕村,調(diào)用take()或者是peek()方法返回null而不是拋出異常
阻塞一直等待的:添加元素:put(e),刪除元素:take()
當(dāng)隊(duì)列滿的時(shí)候聊替,再向隊(duì)列中添加元素,隊(duì)列會(huì)進(jìn)入阻塞狀態(tài)培廓,直到元素添加成功為止惹悄。
當(dāng)隊(duì)列為空的時(shí)候,再?gòu)年?duì)列刪除元素肩钠,隊(duì)列會(huì)阻塞泣港,直到能夠刪除元素為止。
帶有超時(shí)時(shí)間的阻塞:添加元素:offer(e,time,unit),刪除元素:poll(time,unit)
當(dāng)隊(duì)列滿的時(shí)候价匠,調(diào)用offer(e,time,unit)會(huì)進(jìn)入阻塞等待中当纱,當(dāng)過(guò)來(lái)超時(shí)時(shí)間,退出等待
當(dāng)隊(duì)列為空的時(shí)候踩窖,調(diào)用poll(time,unit)方法會(huì)進(jìn)入等待狀態(tài)坡氯,當(dāng)?shù)搅顺瑫r(shí)時(shí)間,會(huì)退出等待洋腮。
四組API總結(jié):
關(guān)于四組API更詳細(xì)的介紹歡迎學(xué)習(xí):《Java阻塞隊(duì)列的四組API》箫柳。在這篇文章中凱哥做了詳細(xì)的介紹。用人的一生四個(gè)階段來(lái)比擬這四組API啥供。
到此悯恍,我們已經(jīng)把Java中隊(duì)列介紹完畢。接下來(lái)伙狐,凱哥將帶著大家一起學(xué)習(xí)線程池涮毫。歡迎大家繼續(xù)學(xué)習(xí)。