Java 阻塞隊列

BlockingQueue類圖

BlockingQueue

BlockingQueue接口實現(xiàn)Queue接口卿拴,它支持兩個附加操作:獲取元素時等待隊列變?yōu)榉强眨约按鎯υ貢r等待空間變得可用梨与。相對于同一操作他提供了四種機制:拋出異常堕花、返回特殊值、阻塞等待粥鞋、超時:

BlockingQueue操作

BlockingQueue常用于生產(chǎn)者和消費者場景缘挽。

JDK 8 中提供了七個阻塞隊列可供使用(上圖的DelayedWorkQueue是ScheduledThreadPoolExecutor的內(nèi)部類):

  • ArrayBlockingQueue :一個由數(shù)組結(jié)構(gòu)組成的有界阻塞隊列。
  • LinkedBlockingQueue :一個由鏈表結(jié)構(gòu)組成的無界阻塞隊列呻粹。
  • PriorityBlockingQueue :一個支持優(yōu)先級排序的無界阻塞隊列壕曼。
  • DelayQueue:一個使用優(yōu)先級隊列實現(xiàn)的無界阻塞隊列。
  • SynchronousQueue:一個不存儲元素的阻塞隊列等浊。
  • LinkedTransferQueue:一個由鏈表結(jié)構(gòu)組成的無界阻塞隊列腮郊。
  • LinkedBlockingDeque:一個由鏈表結(jié)構(gòu)組成的雙向阻塞隊列。

ArrayBlockingQueue

基于數(shù)組的阻塞隊列筹燕,ArrayBlockingQueue內(nèi)部維護這一個定長數(shù)組轧飞,阻塞隊列的大小在初始化時就已經(jīng)確定了,其后無法更改撒踪。

采用可重入鎖ReentrantLock來保證線程安全性过咬,但是生產(chǎn)者和消費者是共用同一個鎖對象,這樣勢必會導致降低一定的吞吐量制妄。當然ArrayBlockingQueue完全可以采用分離鎖來實現(xiàn)生產(chǎn)者和消費者的并行操作掸绞,但是我認為這樣做只會給代碼帶來額外的復雜性,對于性能而言應該不會有太大的提升忍捡,因為基于數(shù)組的ArrayBlockingQueue在數(shù)據(jù)的寫入和讀取操作已經(jīng)非常輕巧了集漾。

ArrayBlockingQueue支持公平性和非公平性切黔,默認采用非公平模式,可以通過構(gòu)造函數(shù)設(shè)置為公平訪問策略(true)具篇。

PriorityBlockingQueue

PriorityBlockingQueue是支持優(yōu)先級的無界隊列纬霞。默認情況下采用自然順序排序,當然也可以通過自定義Comparator來指定元素的排序順序驱显。

PriorityBlockingQueue內(nèi)部采用二叉堆的實現(xiàn)方式诗芜,整個處理過程并不是特別復雜。添加操作則是不斷“上冒”埃疫,而刪除操作則是不斷“下掉”伏恐。

DelayQueue

DelayQueue是一個支持延時操作的無界阻塞隊列。列頭的元素是最先“到期”的元素栓霜,如果隊列里面沒有元素到期翠桦,是不能從列頭獲取元素的,哪怕有元素也不行胳蛮。也就是說只有在延遲期滿時才能夠從隊列中去元素销凑。

它主要運用于如下場景:

  • 緩存系統(tǒng)的設(shè)計:緩存是有一定的時效性的,可以用DelayQueue保存緩存的有效期仅炊,然后利用一個線程查詢DelayQueue斗幼,如果取到元素就證明該緩存已經(jīng)失效了。
  • 定時任務的調(diào)度:DelayQueue保存當天將要執(zhí)行的任務和執(zhí)行時間抚垄,一旦取到元素(任務)蜕窿,就執(zhí)行該任務。

DelayQueue采用支持優(yōu)先級的PriorityQueue來實現(xiàn)呆馁,但是隊列中的元素必須要實現(xiàn)Delayed接口桐经,Delayed接口用來標記那些應該在給定延遲時間之后執(zhí)行的對象,該接口提供了getDelay()方法返回元素節(jié)點的剩余時間智哀。同時次询,元素也必須要實現(xiàn)compareTo()方法,compareTo()方法需要提供與getDelay()方法一致的排序瓷叫。

SynchronousQueue

SynchronousQueue是一個神奇的隊列,他是一個不存儲元素的阻塞隊列送巡,也就是說他的每一個put操作都需要等待一個take操作摹菠,否則就不能繼續(xù)添加元素了,有點兒像Exchanger骗爆,類似于生產(chǎn)者和消費者進行交換次氨。

隊列本身不存儲任何元素,所以非常適用于傳遞性場景摘投,兩者直接進行對接煮寡。其吞吐量會高于ArrayBlockingQueue和LinkedBlockingQueue虹蓄。

SynchronousQueue支持公平和非公平的訪問策略,在默認情況下采用非公平性幸撕,也可以通過構(gòu)造函數(shù)來設(shè)置為公平性薇组。

SynchronousQueue的實現(xiàn)核心為Transferer接口,該接口有TransferQueue和TransferStack兩個實現(xiàn)類坐儿,分別對應著公平策略和非公平策略律胀。接口Transferer有一個tranfer()方法,該方法定義了轉(zhuǎn)移數(shù)據(jù)貌矿,如果e != null炭菌,相當于將一個數(shù)據(jù)交給消費者,如果e == null逛漫,則相當于從一個生產(chǎn)者接收一個消費者交出的數(shù)據(jù)黑低。

LinkedTransferQueue

LinkedTransferQueue是一個由鏈表組成的的無界阻塞隊列,該隊列是一個相當牛逼的隊列:它是ConcurrentLinkedQueue酌毡、SynchronousQueue (公平模式下)克握、無界的LinkedBlockingQueues等的超集。

與其他BlockingQueue相比阔馋,他多實現(xiàn)了一個接口TransferQueue玛荞,該接口是對BlockingQueue的一種補充,多了tryTranfer()和transfer()兩類方法:

  • tranfer():若當前存在一個正在等待獲取的消費者線程呕寝,即立刻移交之勋眯。 否則,會插入當前元素e到隊列尾部下梢,并且等待進入阻塞狀態(tài)客蹋,到有消費者線程取走該元素
  • tryTranfer(): 若當前存在一個正在等待獲取的消費者線程(使用take()或者poll()函數(shù)),使用該方法會即刻轉(zhuǎn)移/傳輸對象元素e孽江;若不存在讶坯,則返回false,并且不進入隊列岗屏。這是一個不阻塞的操作

LinkedBlockingDeque

LinkedBlockingDeque是一個有鏈表組成的雙向阻塞隊列辆琅,與前面的阻塞隊列相比它支持從兩端插入和移出元素。以first結(jié)尾的表示從對頭操作这刷,以last結(jié)尾的表示從對尾操作婉烟。

在初始化LinkedBlockingDeque時可以初始化隊列的容量,用來防止其再擴容時過渡膨脹暇屋。另外雙向阻塞隊列可以運用在“工作竊取”模式中似袁。

擴展閱讀

【死磕Java并發(fā)】—–J.U.C之阻塞隊列:ArrayBlockingQueue
【死磕Java并發(fā)】—–J.U.C之阻塞隊列:PriorityBlockingQueue
【死磕Java并發(fā)】—–J.U.C之阻塞隊列:DelayQueue
【死磕Java并發(fā)】—–J.U.C之阻塞隊列:SynchronousQueue
【死磕Java并發(fā)】—–J.U.C之阻塞隊列:LinkedTransferQueue
【死磕Java并發(fā)】—–J.U.C之阻塞隊列:LinkedBlockingDeque

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子昙衅,更是在濱河造成了極大的恐慌扬霜,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件而涉,死亡現(xiàn)場離奇詭異著瓶,居然都是意外死亡,警方通過查閱死者的電腦和手機婴谱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進店門蟹但,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人谭羔,你說我怎么就攤上這事华糖。” “怎么了瘟裸?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵客叉,是天一觀的道長。 經(jīng)常有香客問我话告,道長兼搏,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任沙郭,我火速辦了婚禮佛呻,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘病线。我一直安慰自己吓著,他們只是感情好,可當我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布送挑。 她就那樣靜靜地躺著绑莺,像睡著了一般。 火紅的嫁衣襯著肌膚如雪惕耕。 梳的紋絲不亂的頭發(fā)上纺裁,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天,我揣著相機與錄音司澎,去河邊找鬼欺缘。 笑死,一個胖子當著我的面吹牛挤安,可吹牛的內(nèi)容都是我干的浪南。 我是一名探鬼主播,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼漱受,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起昂羡,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤絮记,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后虐先,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體怨愤,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年蛹批,在試婚紗的時候發(fā)現(xiàn)自己被綠了撰洗。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡腐芍,死狀恐怖差导,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情猪勇,我是刑警寧澤设褐,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站泣刹,受9級特大地震影響助析,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜椅您,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一外冀、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧掀泳,春花似錦雪隧、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至固灵,卻和暖如春捅伤,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背巫玻。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工丛忆, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人仍秤。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓熄诡,卻偏偏與公主長得像,于是被迫代替她去往敵國和親诗力。 傳聞我的和親對象是個殘疾皇子凰浮,可洞房花燭夜當晚...
    茶點故事閱讀 45,055評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 隊列有長度限制,當隊列中滿了,往隊列中放元素的動作會被阻塞袜茧,當隊列是空的時候菜拓,往隊列中拿元素,這個拿的動作會被阻塞...
    zzq_nene閱讀 351評論 0 1
  • 在并發(fā)編程中笛厦,有時候需要使用線程安全的隊列纳鼎。如果要實現(xiàn)一個線程安全的隊列有兩種方式:一種是使用阻塞算法,另一種是使...
    科大醉俠閱讀 7,353評論 2 2
  • 阻塞隊列裳凸,關(guān)鍵字是阻塞贱鄙,先理解阻塞的含義,在阻塞隊列中姨谷,線程阻塞有這樣的兩種情況: 當隊列中沒有數(shù)據(jù)的情況下逗宁,消費...
    架構(gòu)師奶爸閱讀 933評論 0 3
  • 今天感恩節(jié)哎,感謝一直在我身邊的親朋好友菠秒。感恩相遇疙剑!感恩不離不棄。 中午開了第一次的黨會践叠,身份的轉(zhuǎn)變要...
    迷月閃星情閱讀 10,567評論 0 11
  • 彩排完言缤,天已黑
    劉凱書法閱讀 4,218評論 1 3