BlockingQueue 使用(生產(chǎn)者-消費(fèi)者)

java.util.concurrent包中的Java BlockingQueue接口表示一個(gè)線程安全的隊(duì)列碰凶,可以放入并獲取實(shí)例边翼。
在這篇文章中疮蹦,我會(huì)告訴你如何使用這個(gè)BlockingQueue姿锭。

本文將不討論如何在Java中實(shí)現(xiàn)BlockingQueue。如果您對此感興趣壹粟,在我的偏理論的Java并發(fā)教程中有一個(gè)關(guān)于阻塞隊(duì)列的文章。

BlockingQueue 使用

BlockingQueue通常用于使線程產(chǎn)生對象宿百,而另一線程則使用該對象趁仙。這是一張闡明這一原理的圖表。


BlockingQueue有一個(gè)線程放入它垦页,另一個(gè)線程從中取出

生產(chǎn)線程將持續(xù)生產(chǎn)新對象并將它們插入隊(duì)列雀费,直到隊(duì)列達(dá)到它可以包含的上限。換句話說痊焊,這是極限盏袄。如果阻塞隊(duì)列達(dá)到其上限,則會(huì)在嘗試插入新對象時(shí)阻塞生產(chǎn)線程薄啥。在消耗線程將對象帶出隊(duì)列之前辕羽,它一直處于阻塞狀態(tài)。

消費(fèi)線程不斷將對象從阻塞隊(duì)列中取出垄惧,并對其進(jìn)行處理刁愿。如果消費(fèi)線程試圖將對象從空隊(duì)列中取出,則消費(fèi)線程將被阻塞到逊,直到生成的線程將對象放入隊(duì)列铣口。

BlockingQueue 方法

BlockingQueue有4種不同的方法來插入、刪除和檢查隊(duì)列中的元素觉壶。每一組方法的行為都是不同的脑题,以防被請求的操作不能立即執(zhí)行。下面是這些方法的一個(gè)表:

Throws Exception 特殊值 阻塞 超時(shí)
Insert add(o) offer(o) put(o) offer(o, timeout, timeunit)
Remove remove(o) poll() take() poll(timeout, timeunit)
Examine element() peek()

這四種不同的行為方式意思

  1. Throws Exception: 如果嘗試的操作不可能立即發(fā)生铜靶,則拋出一個(gè)異常叔遂。
  2. 特殊值:如果嘗試的操作不能立即執(zhí)行,則會(huì)返回一個(gè)特殊值(通常為true / false)。
  3. 阻塞:如果嘗試的操作不可能立即執(zhí)行掏熬,那么該方法將阻塞佑稠。
  4. 超時(shí):如果嘗試的操作不可能立即執(zhí)行,則該方法調(diào)用將阻塞旗芬,但不會(huì)超過給定的超時(shí)舌胶。
    返回一個(gè)特殊值,告訴操作是否成功(通常為true / false)疮丛。

無法將null插入到BlockingQueue中幔嫂。如果嘗試插入null,則BlockingQueue將引發(fā)NullPointerException誊薄。

也可以訪問BlockingQueue中的所有元素履恩,而不僅僅是開始和結(jié)束處的元素。例如呢蔫,假設(shè)你需要處理隊(duì)列中的一個(gè)對象切心,但你的應(yīng)用程序決定不處理它。然后你可以調(diào)用remove(o)刪除隊(duì)列中的特定對象片吊。但是绽昏,這并不是非常有效,所以除非你真的需要俏脊,否則不應(yīng)該使用這些Collection方法

BlockingQueue 實(shí)現(xiàn)

由于BlockingQueue是一個(gè)接口全谤,因此您需要使用它的一個(gè)實(shí)現(xiàn)來使用它。java.util.concurrent包具有以下BlockingQueue接口(在Java 6中)的實(shí)現(xiàn):

BlockingQueue 例子

這是一個(gè)Java BlockingQueue示例爷贫。該示例使用BlockingQueue接口的ArrayBlockingQueue實(shí)現(xiàn)认然。

首先,BlockingQueueExample類在不同的線程中啟動(dòng)生產(chǎn)者和消費(fèi)者漫萄。生產(chǎn)者將字符串插入共享BlockingQueue中卷员,消費(fèi)者將它們?nèi)〕觥?/p>

public class BlockingQueueExample {

    public static void main(String[] args) throws Exception {

        BlockingQueue queue = new ArrayBlockingQueue(1024);

        Producer producer = new Producer(queue);
        Consumer consumer = new Consumer(queue);

        new Thread(producer).start();
        new Thread(consumer).start();

        Thread.sleep(4000);
    }
}

這是生產(chǎn)者類。注意它在每個(gè)put()調(diào)用之間的使用sleep腾务。這將導(dǎo)致消費(fèi)者在等待隊(duì)列中的對象時(shí)阻塞子刮。

public class Producer implements Runnable{

    protected BlockingQueue queue = null;

    public Producer(BlockingQueue queue) {
        this.queue = queue;
    }

    public void run() {
        try {
            queue.put("1");
            Thread.sleep(1000);
            queue.put("2");
            Thread.sleep(1000);
            queue.put("3");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

這是消費(fèi)者類。
它只是從隊(duì)列中取出對象窑睁,并將它們打印到System.out挺峡。

public class Consumer implements Runnable{

    protected BlockingQueue queue = null;

    public Consumer(BlockingQueue queue) {
        this.queue = queue;
    }

    public void run() {
        try {
            System.out.println(queue.take());
            System.out.println(queue.take());
            System.out.println(queue.take());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

[原文](http://tutorials.jenkov.com/java-util-concurrent/blockingqueue.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市担钮,隨后出現(xiàn)的幾起案子橱赠,更是在濱河造成了極大的恐慌,老刑警劉巖箫津,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件狭姨,死亡現(xiàn)場離奇詭異,居然都是意外死亡饼拍,警方通過查閱死者的電腦和手機(jī)赡模,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來师抄,“玉大人漓柑,你說我怎么就攤上這事∵端保” “怎么了辆布?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長茶鉴。 經(jīng)常有香客問我锋玲,道長,這世上最難降的妖魔是什么涵叮? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任惭蹂,我火速辦了婚禮,結(jié)果婚禮上割粮,老公的妹妹穿的比我還像新娘盾碗。我一直安慰自己,他們只是感情好穆刻,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著杠步,像睡著了一般氢伟。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上幽歼,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天朵锣,我揣著相機(jī)與錄音,去河邊找鬼甸私。 笑死诚些,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的皇型。 我是一名探鬼主播诬烹,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼弃鸦!你這毒婦竟也來了绞吁?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤唬格,失蹤者是張志新(化名)和其女友劉穎家破,沒想到半個(gè)月后颜说,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡汰聋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年门粪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片烹困。...
    茶點(diǎn)故事閱讀 38,650評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡玄妈,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出韭邓,到底是詐尸還是另有隱情措近,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布女淑,位于F島的核電站瞭郑,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏鸭你。R本人自食惡果不足惜屈张,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望袱巨。 院中可真熱鬧阁谆,春花似錦、人聲如沸愉老。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嫉入。三九已至焰盗,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間咒林,已是汗流浹背熬拒。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留垫竞,地道東北人澎粟。 一個(gè)月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像欢瞪,于是被迫代替她去往敵國和親活烙。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評論 2 349