隊列(Queue):FIFO
雙端隊列(Deque):兩端都可以進出颜价,當我們約束從隊列的一端進出隊列時,就形成了一種存取模式,它遵循先進后出的原則彬向,就是所謂棧結構
阻塞隊列(BlockingQueue):在隊列的基礎上附加了兩個操作,1:在隊列為空時攻冷,獲取元素的線程會等待隊列變?yōu)榉强胀薜ǎ划旉犃袧M時,存儲元素的線程會等待隊列可用等曼,阻塞隊列常用于生產(chǎn)者和消費者場景
1里烦、阻塞隊列:BlockingQueue(T),所有的阻塞隊列的父接口
? ? 首先是接口的繼承關系如圖1-1禁谦,這里可以清楚的看到BlockingQueue隊列其實本質上可以認為是一個集合
常用方法:
? ? (1):add胁黑,添加到隊列里面,如果可以容納州泊,返回true丧蘸,否則直接拋出異常
????(2):offer,表示將元素添加到隊列中遥皂,可以容納返回true力喷,否則返回false
? ? (3):put刽漂,把元素添加到隊列,如果沒有空間弟孟,則阻塞線程
? ? (4):poll贝咙,取走排在首位的對象,如果不能立即取走拂募,則等待入?yún)⒌臅r間庭猩,到時直接返回null
? ? (5):take,取走排在首位的對象没讲,如果為空眯娱,則阻塞隊列,直到有新的對象被加入
? ? 注意:BlockingQueue中不接受null元素爬凑,如果試圖添加一個null的時候徙缴,有可能會拋出空指針異常
2、數(shù)組阻塞隊列ArrayBlockingQueue
? ? 是一個由數(shù)組支持的有界的阻塞隊列FIFO嘁信,從結構來看如圖2-1于样,是一個阻塞隊列,實現(xiàn)方式就是簡單的數(shù)組潘靖,這個一樣也具有數(shù)組的特性穿剖,比較突出的一點就是一旦初始化過后,就無法再進行擴容
3卦溢、鏈表阻塞隊列LinkedBlockingQueue
? ? 基于鏈表的阻塞隊列糊余,結構圖如下圖3-1
我們可以看出,鏈表阻塞隊列和數(shù)組阻塞隊列結構基本相同单寂,從實現(xiàn)方式來看贬芥,
對比數(shù)組隊列和鏈表隊列異同點:
? ? 1).隊列大小有所不同,ArrayBlockingQueue是有界的初始化必須指定大小宣决,而LinkedBlockingQueue可以是有界的也可以是無界的(Integer.MAX_VALUE)蘸劈,對于后者而言,當添加速度大于移除速度時尊沸,在無界的情況下威沫,可能會造成內存溢出等問題。
? ? 2).數(shù)據(jù)存儲容器不同洼专,ArrayBlockingQueue采用的是數(shù)組作為數(shù)據(jù)存儲容器棒掠,而LinkedBlockingQueue采用的則是以Node節(jié)點作為連接對象的鏈表。
????3).由于ArrayBlockingQueue采用的是數(shù)組的存儲容器,因此在插入或刪除元素時不會產(chǎn)生或銷毀任何額外的對象實例,而LinkedBlockingQueue則會生成一個額外的Node對象灶芝。這可能在長時間內需要高效并發(fā)地處理大批量數(shù)據(jù)的時霞篡,對于GC可能存在較大影響玛追。
????4).兩者的實現(xiàn)隊列添加或移除的鎖不一樣但两,ArrayBlockingQueue實現(xiàn)的隊列中的鎖是沒有分離的胳施,即添加操作和移除操作采用的同一個ReenterLock鎖奇适,而LinkedBlockingQueue實現(xiàn)的隊列中的鎖是分離的谜酒,其添加采用的是putLock叹俏,移除采用的則是takeLock,這樣能大大提高隊列的吞吐量僻族,也意味著在高并發(fā)的情況下生產(chǎn)者和消費者可以并行地操作隊列中的數(shù)據(jù)粘驰,以此來提高整個隊列的并發(fā)性能。
4述么、優(yōu)先級阻塞隊列PriorityBlockingQueue
? ? 首先先查看結構蝌数,如圖4-1
? ? 優(yōu)先級阻塞隊列是一個支持優(yōu)先級排序的無界阻塞隊列,優(yōu)先級的判斷通過構造方法傳入的Compator對象來決定度秘,如果通過這個排序構造進行創(chuàng)建對象顶伞,生產(chǎn)的數(shù)據(jù)會排列好放入隊列中。
????PriorityBlockingQueue是基于數(shù)組方式的隊列剑梳,因為排序需要大量的查詢操作唆貌,所以此處通過數(shù)組的方式,查詢排序速度足夠快垢乙,但是因為數(shù)組是有限的锨咙,而PriorityBlockingQueue是無界的,所以中間還需要進行數(shù)組的擴容算法追逮。
? ? 要注意一點酪刀,PriorityBlockingQueue并不會阻塞生產(chǎn)者,只會阻塞消費者钮孵,所以生產(chǎn)者的生產(chǎn)速度絕對不能超過消費者的消費速度骂倘,否則容易內存溢出
? ? 5、延時隊列DelayQueue
????DelayQueue是一個支持延時獲取元素的使用優(yōu)先級隊列的實現(xiàn)的無界阻塞隊列
? ? 在創(chuàng)建元素的時候可以制定多久才能從隊列中獲取當前元素油猫,只有在延遲期滿時才能從隊列中提取元素,一個比較典型的應用場景就是定時任務調度柠偶,生產(chǎn)者將需要執(zhí)行的任務添加到隊列中情妖,時間到之后,消費者從隊列中獲取任務開始執(zhí)行诱担;除了這個我們還可以逆向思維來作為緩存定時任務毡证,就是在把緩存數(shù)據(jù)放入內存中的同時,也把數(shù)據(jù)放入隊列中蔫仙,并添加緩存的時效時間料睛,一旦到達時間,消費者從隊列中讀取到緩存,然后把讀取到的隊列充緩存中刪除恤煞,這樣就可以起到緩存定時的作用屎勘。
????首先看一下DelayQueue的結構,如圖5-1
? ? 從源碼來看居扒,DelayQueue是在PriorityBlockingQueue的基礎上進行擴展 ;