一桐猬、常見的BlockingQueue
1. ArrayBlockingQueue
由數(shù)組支持的有界隊列,內(nèi)部維護(hù)一個定長數(shù)組刽肠。
生產(chǎn)者與消費(fèi)者公用同一個鎖控制數(shù)據(jù)同步溃肪。
處理過程:當(dāng)生產(chǎn)者往隊列存放數(shù)據(jù)時免胃,當(dāng)隊列達(dá)到最大容量時才會阻塞生產(chǎn)者隊列,并且喚醒消費(fèi)者惫撰;當(dāng)消費(fèi)者將隊列元素全部取出羔沙,隊列為空時才會阻塞消費(fèi)者,并且喚醒生產(chǎn)者厨钻。
先進(jìn)先出(FIFO)
默認(rèn)非公平鎖扼雏,可指定為公平鎖。
使用Condition的等待/通知機(jī)制夯膀,使得ArrayBlockingQueue的數(shù)據(jù)寫入和獲取操作足夠輕巧诗充,不需分別使用獨(dú)立生產(chǎn)-消費(fèi)鎖
2. LinkedBlockingQueue
由鏈接節(jié)點(diǎn)支持的可選有界隊列,內(nèi)部維護(hù)一個緩沖隊列诱建,由鏈表構(gòu)成蝴蜓。
生產(chǎn)者與消費(fèi)者采用獨(dú)立的鎖控制數(shù)據(jù)同步。
處理過程:當(dāng)生產(chǎn)者往隊列存放數(shù)據(jù)時涂佃,只有隊列達(dá)到最大容量時(構(gòu)造函數(shù)指定)励翼,才會阻塞生產(chǎn)者隊列蜈敢,當(dāng)消費(fèi)者從隊列消費(fèi)掉一條數(shù)據(jù)時辜荠,生產(chǎn)者線程會被喚醒。消費(fèi)者同理抓狭,當(dāng)緩沖區(qū)無數(shù)據(jù)時伯病,阻塞,有數(shù)據(jù)時喚醒否过。
注:默認(rèn)LinkedBlockingQueue構(gòu)造方法沒有指定容量大小午笛,默認(rèn)無限大Integer.MAX_VALUE,而生產(chǎn)者消費(fèi)者是同時進(jìn)行的苗桂,所以要避免生產(chǎn)者生產(chǎn)速度遠(yuǎn)大于消費(fèi)者消費(fèi)速度的情況药磺,防止堆內(nèi)存耗盡。
先進(jìn)先出(FIFO)
非公平鎖
添加和刪除隊列中的元素的時候煤伟,會創(chuàng)建和銷毀節(jié)點(diǎn)對象癌佩,在高并發(fā)和大量數(shù)據(jù)的時候,GC壓力很大
3. PriorityBlockingQueue
由優(yōu)先級堆支持的無界優(yōu)先級隊列便锨,優(yōu)先級由傳入的Compator決定围辙,內(nèi)部維護(hù)一個數(shù)組。
處理過程:不會阻塞生產(chǎn)者生產(chǎn)數(shù)據(jù)放案,只會在沒有可消費(fèi)的數(shù)據(jù)時姚建,阻塞消費(fèi)者。
注:避免生產(chǎn)者生產(chǎn)速度遠(yuǎn)大于消費(fèi)者消費(fèi)速度的情況吱殉,防止堆內(nèi)存耗盡掸冤。
非公平鎖
4. DelayQueue
由優(yōu)先級堆支持的厘托、基于時間的無界調(diào)度隊列
(DelayQueue入隊的對象必須要實現(xiàn)Delayed接口,而Delayed集成自Comparable接口)
處理過程:只有當(dāng)期指定的延遲時間到了,才會從隊列中獲取該元素稿湿。DelayQueue是一個沒有大小限制的隊列催烘,因此往隊列中插入數(shù)據(jù)的操作(生產(chǎn)者)永遠(yuǎn)不會被阻塞,而只有獲取數(shù)據(jù)的操作(消費(fèi)者)才會被阻塞缎罢。
場景:
緩存系統(tǒng)的設(shè)計:可以用DelayQueue保存緩存元素的有效期伊群,使用一個線程循環(huán)查詢DelayQueue,一旦能從DelayQueue中獲取元素時策精,表示緩存有效期到了舰始。
定時任務(wù)調(diào)度:使用DelayQueue保存當(dāng)天將會執(zhí)行的任務(wù)和執(zhí)行時間,一旦從DelayQueue中獲取到任務(wù)就開始執(zhí)行咽袜,比如TimerQueue就是使用DelayQueue實現(xiàn)的
非公平鎖
5. SynchronousQueue
無緩沖的阻塞隊列丸卷,不存儲元素。
處理過程:
生產(chǎn)者生產(chǎn)操作必須等待一個消費(fèi)操作询刹,否則不能繼續(xù)添加元素谜嫉。
支持公平鎖,非公平鎖
特點(diǎn)
ArrayBlockingQueue
生產(chǎn)者與消費(fèi)者公用一個鎖控制數(shù)據(jù)同步
生產(chǎn)->隊列滿了->阻塞
消費(fèi)->隊列空了->阻塞
生產(chǎn)與消費(fèi)是交替進(jìn)行的凹联,因為是同一把鎖沐兰。
LinkedBlockingQueue
生產(chǎn)者與消費(fèi)者采用獨(dú)立鎖控制數(shù)據(jù)同步
生產(chǎn)->隊列滿了->阻塞
消費(fèi)->隊列空了->阻塞
生產(chǎn)與消費(fèi)是同時進(jìn)行的,有生產(chǎn)就可以消費(fèi)蔽挠。
SynchronousQueue
無緩沖隊列
生產(chǎn)->消費(fèi)(未消費(fèi)則阻塞生產(chǎn))
生產(chǎn)者生產(chǎn)一個必須等待一個消費(fèi)操作住闯,否則不能繼續(xù)添加元素
PriorityBlockingQueue
優(yōu)先級無界隊列,由傳入的Compator決定優(yōu)先級
生產(chǎn)->消費(fèi)->消費(fèi)空了->阻塞
生產(chǎn)不阻塞澳淑,消費(fèi)空了阻塞比原,生產(chǎn)者生產(chǎn)過快容易內(nèi)存耗盡
DelayQueue
基于時間優(yōu)先級的無界隊列,入隊的對象要實現(xiàn)Delayed接口杠巡,該接口實現(xiàn)了Comparable接口
生產(chǎn)->延遲時間到了->消費(fèi)->消費(fèi)空了->阻塞
生產(chǎn)不阻塞量窘,消費(fèi)空了阻塞。定時任務(wù)可基于該隊列處理
二氢拥、阻塞的實現(xiàn)
ReentranLock + Condition 實現(xiàn)隊列的阻塞蚌铜,ReentranLock是鎖,Condition是條件狀態(tài)兄一,通過等待/通知機(jī)制蓝仲,來實現(xiàn)線程之間的通信捷兰。
ReentranLock + Condition的等待/通知機(jī)制和Object的wait()與notify()是類似的励烦,通過synchronized芝发,在鎖中使用wait()與notify()達(dá)到線程之間通信,在ReentranLock的lock()和unlock()之間通過類似的await()和signal()達(dá)到線程之間的通信。
Condition條件隊列
條件隊列是不會被喚醒競爭鎖的耳璧,如果條件隊列的線程需要被喚醒競爭鎖資源需要被轉(zhuǎn)移到CLH等待隊列中才可以成箫。
在阻塞隊列中A調(diào)用put()方法的時候,如果隊列已滿旨枯,則A線程掛起蹬昌,等待恢復(fù),如果B線程調(diào)用take()后攀隔,消耗一個隊列元素后皂贩,會通知put()方法中掛起的A線程,因為這個時候B線程已經(jīng)消耗一個元素可以在向隊列中添加元素昆汹。相反如果隊列一空 B線程調(diào)用tack()方法會阻塞明刷,當(dāng)A線程調(diào)用put()調(diào)用后通知tack()方法中的B線程,有元素可以獲取满粗。這就是阻塞的實現(xiàn)過程辈末。
三、BlockingQueue的核心方法
1. 生產(chǎn)者生產(chǎn)數(shù)據(jù)
boolean add(E e);
將指定的元素插入到此隊列中映皆,如果成功則返回true挤聘,如果當(dāng)前沒有空間可用則拋出IllegalStateException。當(dāng)使用容量受限的隊列時捅彻,通常更可取的做法是使用offer()方法组去。
boolean offer(E e);
將指定的元素插入到此隊列中,如果成功則返回true沟饥,如果當(dāng)前沒有空間可用則返回false添怔。
void put(E e) throws InterruptedException;
將指定的元素插入到此隊列中湾戳,如果當(dāng)前沒有空間則阻塞至有空間可用
boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException;
將指定的元素插入到此隊列中贤旷,如果需要空間可用,則需要等待指定的等待時間砾脑。
2. 消費(fèi)者消費(fèi)數(shù)據(jù)
E take() throws InterruptedException;
獲取隊首元素并刪除幼驶,如當(dāng)前沒有元素則等待至有元素可獲取
E poll(long timeout, TimeUnit unit) throws InterruptedException;
獲取隊首元素并刪除,如果當(dāng)前沒有元素韧衣,則需要等待指定時間
int drainTo();
一次性從隊列中獲取所有可用元素(也可指定個數(shù))盅藻,并將它們添加到給定集合中。此操作可能比重復(fù)輪詢此隊列更有效率畅铭。
參考:https://www.iteye.com/blog/wsmajunfeng-1629354
http://www.reibang.com/p/32665a52eba1