Java 并發(fā)容器 -- BlockingQueue

BlockingQueue接口

Queue

常用方法

Throws exception Returns special value
Insert add offer
Remove remove poll
Examine element peek

Queue接口

package java.util

public interface Queue<E> extends Collection<E> {
    // 向隊列尾部插入一個無素匪傍,如果是有界隊列,此時隊列已滿尘吗,則拋出IllegalStateException異常
    boolean add(E e);
    // 同add方法的區(qū)別是:如果是有界隊列丢郊,此時隊列已滿斗埂,則返回false
    boolean offer(E e);
    // 從隊列的頭部取出一個元素并刪除該無素靠柑。如果隊列是空,則拋出NoSuchElementException異常
    E remove();
    // 同remove方法的區(qū)別是:如果隊列是空鸣哀,則返回null
    E poll();
    // 從隊列的頭部獲取一個元素但不刪除該元素鹰溜,如果隊列是空虽填,則拋出NoSuchElementException異常
    E element();
    // 同element方法的區(qū)別是:如果隊列是空,則返回null
    E peek();
}

Deque

常用方法

  • First element (Head)
  • Last element (Tail)
Throws Exception Returns special value Throws Exception Returns special value
Insert addFirst offerFirst addLast offerLast
Remove removeFirst pollFirst removeLast pollLast
Examine getFirst peekFirst getLast peekLast

Deque與Queue

Queue和Deque的一些方法的功能是一樣的奉狈。如下表:

Queue Method Equivalent Deque Method
add addLast
offer offerLast
remove removeFirst
poll pollFirst
element getFirst
peek peekFirst

Deque與Stack

Deque可以作為LIFO(Last-In-First-Out)卤唉,和Stack一樣。

Stack Method Equivalent Deque Method
push addFirst
pop removeFirst
peek peekFirst

Deque接口

public interface Deque<E> extends Queue<E> {
    // 向隊列的頭部插入一個元素仁期。如果是有界隊列桑驱,此時隊列已滿,則拋出IllegalStateException異常
    void addFirst(E e);
    // 向隊列的尾部插入一個元素跛蛋。如果是有界隊列熬的,此時隊列已滿,則拋出IllegalStateException異常
    void addLast(E e);
    // 向隊列的頭部插入一個元素赊级。如果是有界隊列押框,此時隊列已滿,則返回false
    boolean offerFirst(E e);
    // 向隊列的尾部插入一個元素理逊。如果是有界隊列橡伞,此時隊列已滿,則返回false
    boolean offerLast(E e);
    // 從隊列的頭部取出一個元素并刪除該無素晋被。如果隊列是空兑徘,則拋出NoSuchElementException異常
    E removeFirst();
    // 從隊列的尾部取出一個元素并刪除該無素。如果隊列是空羡洛,則拋出NoSuchElementException異常
    E removeLast();
    // 從隊列的頭部取出一個元素并刪除該無素挂脑。如果隊列是空,則返回null
    E pollFirst();
    // 從隊列的尾部取出一個元素并刪除該無素欲侮。如果隊列是空崭闲,則返回null
    E pollLast();
    // 從隊列的頭部獲取一個元素但不刪除該元素,如果隊列是空威蕉,則拋出NoSuchElementException異常
    E getFirst();
    // 從隊列的尾部獲取一個元素但不刪除該元素刁俭,如果隊列是空,則拋出NoSuchElementException異常
    E getLast();
    // 從隊列的頭部獲取一個元素但不刪除該元素韧涨,如果隊列是空牍戚,則返回null
    E peekFirst();
    // 從隊列的尾部獲取一個元素但不刪除該元素沙兰,如果隊列是空,則返回null
    E peekLast();
    // 刪除隊列第一次出現(xiàn)該元素翘魄。如果不存在則返回false
    boolean removeFirstOccurrence(Object o);
    // 刪除隊列最后一次出現(xiàn)該元素,如果不存在則返回false
    boolean removeLastOccurrence(Object o);

    // *** Queue methods ***
    
    // 同 addLast 方法一樣
    boolean add(E e);
    // 同 offerLast 方法一樣
    boolean offer(E e);
    // 同 removeFirst 方法一樣
    E remove();
    // 同 pollFirst 方法一樣
    E poll();
    // 同 getFirst 方法一樣
    E element();
    // 同 peekFirst 方法一樣
    E peek();


    // *** Stack methods ***
    
    // 同 addFirst 方法一樣
    void push(E e);
    // 同 removeFirst 方法一樣
    E pop();

    // *** Collection methods ***

    // 同 removeFirstOccurrence 方法一樣
    boolean remove(Object o);
    // 隊列中包含指定的元素時返回true(至少有一個), 否則返回false
    boolean contains(Object o);
    // 隊列中的元素個數(shù)
    public int size();
    // 提供從 head -> tail 方式遍歷隊列元素
    Iterator<E> iterator();
    // 提供從 tail -> head 方法遍歷隊列元素
    Iterator<E> descendingIterator();

}

BlockingQueue

BlockingQueue是線程安全的阻塞隊列舀奶。通常用于實現(xiàn)生產(chǎn)者-消費者的情形暑竟。

BlockingQueue新增支持阻塞的相關(guān)方法:

  • 當(dāng)隊列已滿時:則不允許插入元素,此時方法處于阻塞狀態(tài)育勺,直到隊列不為空時但荤,才可以繼續(xù)執(zhí)行。
  • 當(dāng)隊隊列為空時:則不允拿走元素涧至,此時方法處于阻塞狀態(tài)腹躁,直到隊列中有元素時,才可以繼續(xù)執(zhí)行南蓬。

常用方法

Throws exception Returns special value Blocks Times out
Insert add offer put offer(long, TimeUnit)
Remove remove poll take poll(long, TimeUnit)
Examine element peek -- --

BlockingQueue接口

public interface BlockingQueue<E> extends Queue<E> {
    // 向隊列尾部插入一個無素纺非,如果是有界隊列,此時隊列已滿赘方,則拋出IllegalStateException異常
    boolean add(E e);
    // 向隊列尾部插入一個無素烧颖,如果是有界隊列,此時隊列已滿窄陡,則返回false
    boolean offer(E e);
    // 向隊列尾部插入一個無素炕淮,如果是有界隊列,此時隊列已滿跳夭,則調(diào)用此方法的線程處于阻塞狀態(tài)涂圆。注意該方法支持被設(shè)置中斷
    void put(E e) throws InterruptedException;
    // 向隊列尾部插入一個無素,如果是有界隊列币叹,此時隊列已滿润歉,則調(diào)用此方法的線程在指定的時間內(nèi)處于阻塞狀態(tài)。如果指定時間內(nèi)不能插入元素則返回false套硼。注意該方法支持被設(shè)置中斷
    boolean offer(E e, long timeout, TimeUnit unit)
        throws InterruptedException;
    // 從隊列的頭部取出一個元素并刪除該無素卡辰。如果隊列是空,則調(diào)用些方法的線程處于阻塞狀態(tài)邪意。注意該方法支持被設(shè)置中斷九妈。
    E take() throws InterruptedException;
    // 從隊列的頭部取出一個元素并刪除該元素,如果隊列是空雾鬼,則調(diào)用此方法的線程在指定的時間內(nèi)處于阻塞狀態(tài)萌朱。如果指定時間內(nèi)不能獲取到元素,則返回null策菜。注意該方法支持被設(shè)置中斷
    E poll(long timeout, TimeUnit unit)
        throws InterruptedException;
    // 返回隊列中剩余的容量晶疼。注意酒贬,不能用該方法來判斷隊列是否已滿或已空來決定是否插入或拿走操作。
    int remainingCapacity();
    // 從隊列中刪除指定的元素翠霍,如果不存在則返回false
    boolean remove(Object o);
    // 指定元素是否存在隊列中
    public boolean contains(Object o);
    // 刪除隊列中所有元素并添加到Collection集合中锭吨。此方法比重復(fù)執(zhí)行poll方法要更高效。
    int drainTo(Collection<? super E> c);
    // 刪除隊列中指定元素個數(shù)并添加到Collection集合中
    int drainTo(Collection<? super E> c, int maxElements);
}

TransferQueue

TransferQueue提供生產(chǎn)者可以等待(阻塞)消費者收到消息的相關(guān)功能寒匙。如生產(chǎn)者線程調(diào)用transfer方法時零如,必須等到消費者線程調(diào)用take方法或poll方法拿到消息時,生產(chǎn)者線程才可以繼續(xù)往下處理锄弱,否則一直處于阻塞狀態(tài)考蕾。

TransferQueue接口

public interface TransferQueue<E> extends BlockingQueue<E> {
    // 生產(chǎn)者線程嘗試傳輸消息,如果有消費者線程調(diào)用take或poll方法時会宪,該方法返回true肖卧,否則返回false。Non-blocking
    boolean tryTransfer(E e);
    // 生產(chǎn)者傳輸消息掸鹅,如果有消費者線程調(diào)用take或poll方法塞帐,該方法直接返回;否則該線程處于阻塞狀態(tài)
    void transfer(E e) throws InterruptedException;
    // 生產(chǎn)者線程在指定的時間內(nèi)嘗試傳輸消息河劝,如果有消費者線程調(diào)用take或poll方法時壁榕,該方法返回true,如果超出指定時間內(nèi)則返回false
    boolean tryTransfer(E e, long timeout, TimeUnit unit)
        throws InterruptedException;
    // 是否存在有等待獲取消息的消費者
    boolean hasWaitingConsumer();
    // 正在等待獲取消息的消費者的數(shù)量
    int getWaitingConsumerCount();
}

AbstractQueue

AbstractQueue是抽象類實現(xiàn)了部分Queue的方法赎瞎,如add牌里、remove、element方法务甥;繼承了AbstractCollection類牡辽,實現(xiàn)了clear、addAll方法敞临。

AbstractQueue抽象類采用模板方法的設(shè)計模式.

public abstract class AbstractQueue<E>
    extends AbstractCollection<E>
    implements Queue<E> {
    
    protected AbstractQueue() {
    }
    
    public boolean add(E e) {
        // offer方法由子類實現(xiàn)态辛,如果offer方法返回false,則拋IllegalStateException異常
        if (offer(e))
            return true;
        else
            throw new IllegalStateException("Queue full");
    }

    public E remove() {
        // poll方法由子類實現(xiàn)挺尿,如果poll方法返回null奏黑,則拋NoSuchElementException異常
        E x = poll();
        if (x != null)
            return x;
        else
            throw new NoSuchElementException();
    }

    public E element() {
        // peek方法由子類實現(xiàn),如果peek方法返回null编矾,則拋NoSuchElementException異常
        E x = peek();
        if (x != null)
            return x;
        else
            throw new NoSuchElementException();
    }

    public void clear() {
        // 輪徇調(diào)用poll方法刪除隊列中的元素
        while (poll() != null)
            ;
    }
}

小結(jié)

總結(jié)Queue熟史、Deque、BlockingQueue和TransferQueue接口相關(guān)的方法的說明窄俏。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蹂匹,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子凹蜈,更是在濱河造成了極大的恐慌限寞,老刑警劉巖忍啸,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異履植,居然都是意外死亡计雌,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進(jìn)店門玫霎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來白粉,“玉大人,你說我怎么就攤上這事鼠渺。” “怎么了眷细?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵拦盹,是天一觀的道長。 經(jīng)常有香客問我溪椎,道長普舆,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任校读,我火速辦了婚禮沼侣,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘歉秫。我一直安慰自己蛾洛,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布雁芙。 她就那樣靜靜地躺著轧膘,像睡著了一般。 火紅的嫁衣襯著肌膚如雪兔甘。 梳的紋絲不亂的頭發(fā)上谎碍,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天,我揣著相機(jī)與錄音洞焙,去河邊找鬼蟆淀。 笑死,一個胖子當(dāng)著我的面吹牛澡匪,可吹牛的內(nèi)容都是我干的熔任。 我是一名探鬼主播,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼仙蛉,長吁一口氣:“原來是場噩夢啊……” “哼笋敞!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起荠瘪,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤夯巷,失蹤者是張志新(化名)和其女友劉穎赛惩,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體趁餐,經(jīng)...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡喷兼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了后雷。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片季惯。...
    茶點故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖臀突,靈堂內(nèi)的尸體忽然破棺而出勉抓,到底是詐尸還是另有隱情,我是刑警寧澤候学,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布藕筋,位于F島的核電站,受9級特大地震影響梳码,放射性物質(zhì)發(fā)生泄漏隐圾。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一掰茶、第九天 我趴在偏房一處隱蔽的房頂上張望暇藏。 院中可真熱鬧,春花似錦濒蒋、人聲如沸盐碱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽甸各。三九已至,卻和暖如春焰坪,著一層夾襖步出監(jiān)牢的瞬間趣倾,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工某饰, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留儒恋,地道東北人。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓黔漂,卻偏偏與公主長得像诫尽,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子炬守,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,066評論 2 355