Java并發(fā)隊(duì)列BlockingQueue怎么用

這篇文章主要介紹了Java并發(fā)隊(duì)列BlockingQueue怎么用的相關(guān)知識(shí),內(nèi)容詳細(xì)易懂,操作簡單快捷,具有一定借鑒價(jià)值,相信大家閱讀完這篇Java并發(fā)隊(duì)列BlockingQueue怎么用文章都會(huì)有所收獲,下面我們一起來看看吧。

創(chuàng)新互聯(lián)專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于網(wǎng)站設(shè)計(jì)制作、成都網(wǎng)站制作、盱眙網(wǎng)絡(luò)推廣、重慶小程序開發(fā)、盱眙網(wǎng)絡(luò)營銷、盱眙企業(yè)策劃、盱眙品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);創(chuàng)新互聯(lián)為所有大學(xué)生創(chuàng)業(yè)者提供盱眙建站搭建服務(wù),24小時(shí)服務(wù)熱線:13518219792,官方網(wǎng)址:muchs.cn

BlockingQueue

首先,最基本的來說, BlockingQueue 是一個(gè)先進(jìn)先出的隊(duì)列(Queue),為什么說是阻塞(Blocking)的呢?是因?yàn)?BlockingQueue 支持當(dāng)獲取隊(duì)列元素但是隊(duì)列為空時(shí),會(huì)阻塞等待隊(duì)列中有元素再返回;也支持添加元素時(shí),如果隊(duì)列已滿,那么等到隊(duì)列可以放入新元素時(shí)再放入。

BlockingQueue 是一個(gè)接口,繼承自 Queue,所以其實(shí)現(xiàn)類也可以作為 Queue 的實(shí)現(xiàn)來使用,而 Queue 又繼承自 Collection 接口。

BlockingQueue 對(duì)插入操作、移除操作、獲取元素操作提供了四種不同的方法用于不同的場(chǎng)景中使用:1、拋出異常;2、返回特殊值(null 或 true/false,取決于具體的操作);3、阻塞等待此操作,直到這個(gè)操作成功;4、阻塞等待此操作,直到成功或者超時(shí)指定時(shí)間。總結(jié)如下:


Throws exception

Special value

Blocks

Times out

Insertadd(e)offer(e)put(e)offer(e, time, unit)
Removeremove()poll()take()poll(time, unit)
Examineelement()peek()

not applicable

not applicable

BlockingQueue 的各個(gè)實(shí)現(xiàn)都遵循了這些規(guī)則,當(dāng)然我們也不用死記這個(gè)表格,知道有這么回事,然后寫代碼的時(shí)候根據(jù)自己的需要去看方法的注釋來選取合適的方法即可。

對(duì)于 BlockingQueue,我們的關(guān)注點(diǎn)應(yīng)該在 put(e) 和 take() 這兩個(gè)方法,因?yàn)檫@兩個(gè)方法是帶阻塞的。

BlockingQueue 不接受 null 值的插入,相應(yīng)的方法在碰到 null 的插入時(shí)會(huì)拋出 NullPointerException 異常。null 值在這里通常用于作為特殊值返回(表格中的第三列),代表 poll 失敗。所以,如果允許插入 null 值的話,那獲取的時(shí)候,就不能很好地用 null 來判斷到底是代表失敗,還是獲取的值就是 null 值。

一個(gè) BlockingQueue 可能是有界的,如果在插入的時(shí)候,發(fā)現(xiàn)隊(duì)列滿了,那么 put 操作將會(huì)阻塞。通常,在這里我們說的無界隊(duì)列也不是說真正的無界,而是它的容量是 Integer.MAX_VALUE(21億多)。

BlockingQueue 是設(shè)計(jì)用來實(shí)現(xiàn)生產(chǎn)者-消費(fèi)者隊(duì)列的,當(dāng)然,你也可以將它當(dāng)做普通的 Collection 來用,前面說了,它實(shí)現(xiàn)了 java.util.Collection 接口。例如,我們可以用 remove(x) 來刪除任意一個(gè)元素,但是,這類操作通常并不高效,所以盡量只在少數(shù)的場(chǎng)合使用,比如一條消息已經(jīng)入隊(duì),但是需要做取消操作的時(shí)候。

BlockingQueue 的實(shí)現(xiàn)都是線程安全的,但是批量的集合操作如 addAllcontainsAllretainAll 和 removeAll 不一定是原子操作。如 addAll(c) 有可能在添加了一些元素后中途拋出異常,此時(shí) BlockingQueue 中已經(jīng)添加了部分元素,這個(gè)是允許的,取決于具體的實(shí)現(xiàn)。

BlockingQueue 不支持 close 或 shutdown 等關(guān)閉操作,因?yàn)殚_發(fā)者可能希望不會(huì)有新的元素添加進(jìn)去,此特性取決于具體的實(shí)現(xiàn),不做強(qiáng)制約束。

最后,BlockingQueue 在生產(chǎn)者-消費(fèi)者的場(chǎng)景中,是支持多消費(fèi)者和多生產(chǎn)者的,說的其實(shí)就是線程安全問題。

相信上面說的每一句都很清楚了,BlockingQueue 是一個(gè)比較簡單的線程安全容器,下面我會(huì)分析其具體的在 JDK 中的實(shí)現(xiàn),這里又到了 Doug Lea 表演時(shí)間了。

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

ArrayBlockingQueue 是 BlockingQueue 接口的有界隊(duì)列實(shí)現(xiàn)類,底層采用數(shù)組來實(shí)現(xiàn)。

其并發(fā)控制采用可重入鎖來控制,不管是插入操作還是讀取操作,都需要獲取到鎖才能進(jìn)行操作。

ArrayBlockingQueue 共有以下幾個(gè)屬性:

// 用于存放元素的數(shù)組
final Object[] items;
// 下一次讀取操作的位置
int takeIndex;
// 下一次寫入操作的位置
int putIndex;
// 隊(duì)列中的元素?cái)?shù)量
int count;
// 以下幾個(gè)就是控制并發(fā)用的同步器
final ReentrantLock lock;
private final Condition notEmpty;
private final Condition notFull;

我們用個(gè)示意圖來描述其同步機(jī)制:

好了, PriorityBlockingQueue 我們也說完了。

關(guān)于“Java并發(fā)隊(duì)列BlockingQueue怎么用”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對(duì)“Java并發(fā)隊(duì)列BlockingQueue怎么用”知識(shí)都有一定的了解,大家如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

分享文章:Java并發(fā)隊(duì)列BlockingQueue怎么用
文章鏈接:http://muchs.cn/article24/jpgdje.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供自適應(yīng)網(wǎng)站、企業(yè)建站外貿(mào)網(wǎng)站建設(shè)、定制開發(fā)營銷型網(wǎng)站建設(shè)、云服務(wù)器

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

營銷型網(wǎng)站建設(shè)